A. Setting up Camp
题目分析:
有三种人,内向、外向、综合,内向必须独自一个帐篷,外向必须3个人一个帐篷,综合介于1~3人一个帐篷,我们发现非法情况只会存在外向的人凑不成3个人一个帐篷的情况,因外向不够可以向综合人借,故将二者合并并判断:
#include<bits/stdc++.h>
#pragma GCC optimize("Ofast")
#define INF 1e18
#define IOS ios::sync_with_stdio(false);cin.tie(0);
#define int long long
#define pb push_back
#define vct vector
#define checkbit __builtin_popcount
#define gcd __gcd
#define use int T;cin>>T;while(T--)
#define LEN length()
#define all(a) a.begin()+1,a.end()
template<class T> bool mmax(T &u, T v) { return u < v ? (u = v, 1) : 0; }
template<class T> bool mmin(T &u, T v) { return u > v ? (u = v, 1) : 0; }
#define lowbit(x) (x&(-x))
#define yes cout<<"YES"<<'\n'
#define no cout<<"NO"<<'\n'
#define safe_map unordered_map<int, int, custom_hash>
using namespace std;
typedef pair<int,int>pii;
const int N =2e5+7;
struct custom_hash {
size_t operator()(uint64_t x) const {
static const uint64_t FIXED_RANDOM = chrono::steady_clock::now().time_since_epoch().count();
x ^= FIXED_RANDOM;
return x ^ (x >> 16);
}
};
signed main()
{IOS
use{
int a,b,c;cin>>a>>b>>c;
int x=b%3;
if(x+c<3&&x!=0)cout<<"-1"<<endl;// 非法情况
else cout<<a+(b+c)/3+((b+c)%3?1:0)<<endl;//else
}
return 0;
}
B. Fireworks
题目分析:
A类烟花每a分钟发射一次,B类烟花每b分钟发射一次,它们都能持续m分钟,那么我们直接用m分别求出这两类烟花都能放几个加和即可,注意, 我们可以选择烟花发射时间包含二者最小公倍数所以最终结果+2
#include<bits/stdc++.h>
#pragma GCC optimize("Ofast")
#define INF 1e18
#define IOS ios::sync_with_stdio(false);cin.tie(0);
#define int long long
#define pb push_back
#define vct vector
#define checkbit __builtin_popcount
#define gcd __gcd
#define use int T;cin>>T;while(T--)
#define LEN length()
#define all(a) a.begin()+1,a.end()
template<class T> bool mmax(T &u, T v) { return u < v ? (u = v, 1) : 0; }
template<class T> bool mmin(T &u, T v) { return u > v ? (u = v, 1) : 0; }
#define lowbit(x) (x&(-x))
#define yes cout<<"YES"<<'\n'
#define no cout<<"NO"<<'\n'
#define safe_map unordered_map<int, int, custom_hash>
using namespace std;
typedef pair<int,int>pii;
const int N =2e5+7;
struct custom_hash {
size_t operator()(uint64_t x) const {
static const uint64_t FIXED_RANDOM = chrono::steady_clock::now().time_since_epoch().count();
x ^= FIXED_RANDOM;
return x ^ (x >> 16);
}
};
signed main()
{IOS
use{
int a,b,m;cin>>a>>b>>m;
cout<<m/a+m/b+2<<endl;
}
return 0;
}
C. Left and Right Houses
题目分析:
给定字符串s,要求将字符串分隔,并且确保满足题目条件,遍历即可
#include<bits/stdc++.h>
#pragma GCC optimize("Ofast")
#define INF 1e18
#define IOS ios::sync_with_stdio(false);cin.tie(0);
#define int long long
#define pb push_back
#define vct vector
#define checkbit __builtin_popcount
#define gcd __gcd
#define use int T;cin>>T;while(T--)
#define LEN length()
#define all(a) a.begin()+1,a.end()
template<class T> bool mmax(T &u, T v) { return u < v ? (u = v, 1) : 0; }
template<class T> bool mmin(T &u, T v) { return u > v ? (u = v, 1) : 0; }
#define lowbit(x) (x&(-x))
#define yes cout<<"YES"<<'\n'
#define no cout<<"NO"<<'\n'
#define safe_map unordered_map<int, int, custom_hash>
using namespace std;
typedef pair<int,int>pii;
const int N =2e5+7;
struct custom_hash {
size_t operator()(uint64_t x) const {
static const uint64_t FIXED_RANDOM = chrono::steady_clock::now().time_since_epoch().count();
x ^= FIXED_RANDOM;
return x ^ (x >> 16);
}
};
char s[3000005];
int s1[300005];
signed main()
{
use{
int n;cin>>n;
scanf("%s",s+1);
for(int i=1;i<=n;i++)s1[i]=s1[i-1]+(s[i]-48);
int ans=-1;
for(int i=0;i<=n;i++)if(s1[i]<=i-s1[i] && s1[n]-s1[i]>=(n-i)-(s1[n]-s1[i])){
if(abs(n-i-i)<abs(n-ans-ans))ans=i;
}
cout<<ans<<endl;
}
return 0;
}
D. Seraphim the Owl
题目分析:
当主人公在i位置时,他想要换到j位置,首先需要花费 a[j] 元, 并且需要花费
因为主人公需要至少排在第m位,所以在n+1~m-1之间我们可以选择最优值,也就是min(a[i],b[i]),
到m后,我们可以选择a[m]来停下,但是考虑到有可能到前面的位置花费会更小所以我们再向前模拟,更新最小值
#include<bits/stdc++.h>
#pragma GCC optimize("Ofast")
#define INF 1e18
#define IOS ios::sync_with_stdio(false);cin.tie(0);
#define int long long
#define pb push_back
#define vct vector
#define checkbit __builtin_popcount
#define gcd __gcd
#define use int T;cin>>T;while(T--)
#define LEN length()
#define all(a) a.begin()+1,a.end()
template<class T> bool mmax(T &u, T v) { return u < v ? (u = v, 1) : 0; }
template<class T> bool mmin(T &u, T v) { return u > v ? (u = v, 1) : 0; }
#define lowbit(x) (x&(-x))
#define yes cout<<"YES"<<'\n'
#define no cout<<"NO"<<'\n'
#define safe_map unordered_map<int, int, custom_hash>
using namespace std;
typedef pair<int,int>pii;
const int N =2e5+7;
struct custom_hash {
size_t operator()(uint64_t x) const {
static const uint64_t FIXED_RANDOM = chrono::steady_clock::now().time_since_epoch().count();
x ^= FIXED_RANDOM;
return x ^ (x >> 16);
}
};
signed main()
{IOS
use{
int n,m;cin>>n>>m;
vct<int>a(n+1),b(n+1);
for(int i=1;i<=n;i++)cin>>a[i];
for(int i=1;i<=n;i++)cin>>b[i];
int ans=0;
for(int i=n;i>m;i--){
ans+=min(a[i],b[i]);
}
int mins=a[m];
int x=0;
for(int i=m;i>1;i--){
x+=b[i];
mmin(mins,x+a[i-1]);
}
cout<<ans+mins<<'\n';
}
return 0;
}
E. Binary Search
题目分析:
二分但没完全二分,数组的取值为1~n,且可能不单调,题目给出的方法适用于单调递增,故,如果起初数组为单调递增的话操作数为0,否则,我们按照题意进行二分模拟,最终二分出来的坐标l 与x起初的位置换一次即可;
证明可行性,因在原数组模拟的情况下,在过程中l满足小于等于x的性质,x也同样满足小于等于x的性质,故可等价替换,故仅需要一次操作即可二分得到x
#include<bits/stdc++.h>
#pragma GCC optimize("Ofast")
#define INF 1e18
#define IOS ios::sync_with_stdio(false);cin.tie(0);
#define int long long
#define pb push_back
#define vct vector
#define checkbit __builtin_popcount
#define gcd __gcd
#define use int T;cin>>T;while(T--)
#define LEN length()
#define all(a) a.begin()+1,a.end()
template<class T> bool mmax(T &u, T v) { return u < v ? (u = v, 1) : 0; }
template<class T> bool mmin(T &u, T v) { return u > v ? (u = v, 1) : 0; }
#define lowbit(x) (x&(-x))
#define yes cout<<"YES"<<'\n'
#define no cout<<"NO"<<'\n'
#define safe_map unordered_map<int, int, custom_hash>
using namespace std;
typedef pair<int,int>pii;
const int N =2e5+7;
struct custom_hash {
size_t operator()(uint64_t x) const {
static const uint64_t FIXED_RANDOM = chrono::steady_clock::now().time_since_epoch().count();
x ^= FIXED_RANDOM;
return x ^ (x >> 16);
}
};
signed main()
{IOS
use{
int n,x;cin>>n>>x;
vct<int>a(n+1);
int cnt=0;
safe_map mp;
for(int i=1;i<=n;i++){
cin>>a[i];
mp[a[i]]=i;
}
if(is_sorted(all(a)))cout<<"0"<<endl;
else {
cout<<"1"<<endl;
int l=1,r=n+1;
while(l<r-1){
int mid =(l+r)>>1;
if(a[mid]>x)r=mid;
else l=mid;
}
cout<<l<<" "<<mp[x]<<endl;
}
}
return 0;
}
总结:A~E题都可以用模拟or 思维解出.