A. Three swimmers
先分别计算出对于a、b、c在你到达后,并且他们到达原点的时间。
比如对于a,在你到达后他正好游完了a/p个来回,此时使用进一法,ta = (a+p-1)/p,即为你到达后a到达原点的时间.
最后答案ans = min(ta,tb,tc);
代码:
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
#include<string>
#include<vector>
#include<stack>
#include<bitset>
#include<cstdlib>
#include<cmath>
#include<set>
#include<list>
#include<deque>
#include<map>
#include<queue>
using namespace std;
typedef long long ll;
const double PI = acos(-1.0);
const ll INF = 0x3f3f3f3f;
int main(){
std::ios::sync_with_stdio(false);cin.tie(0); cout.tie(0);
#ifndef ONLINE_JUDGE
freopen("../in.txt","r",stdin); freopen("../out.txt","w",stdout);
#endif
ll T,a,b,c,p;
cin>>T; while(T--){
cin>>p>>a>>b>>c;
ll ta = (p+a-1)/a * a - p;
ll tb = (p+b-1)/b * b - p;
ll tc = (p+c-1)/c * c - p;
// cout<<ta<<" "<<tb<<" "<<tc<<"\n";
cout<<min(ta,min(tb,tc))<<"\n";
}
return 0;
}
B. Card Deck
对于新的排列,我们应该尽量将大的牌放在下面。
同时通过计算,我们可以得出当当前最大的牌在最下面的情况,大于所有其他最大牌不在最下面的情况。
所以对牌堆从上到下进行遍历,每次遇到当前可以摸到的最大的牌时就将所有的牌放入新的牌堆。
我们可以建一个数组book[maxn]进行优化,当当前数为i的牌被摸到后book[i] = 1;初始时最大的牌为n,这样就可以在摸到最大的牌后很快的确定剩下的牌中最大牌的数字。
代码:
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
#include<string>
#include<vector>
#include<stack>
#include<bitset>
#include<cstdlib>
#include<cmath>
#include<set>
#include<list>
#include<deque>
#include<map>
#include<queue>
using namespace std;
typedef long long ll;
const double PI = acos(-1.0);
const int INF = 0x3f3f3f3f;
const int maxn = 1e5+5;
int a[maxn],book[maxn];
void put(int l,int r){
for(int i=l;i<=r;i++) cout<<a[i]<<" ";
}
int main(){
std::ios::sync_with_stdio(false);cin.tie(0); cout.tie(0);
#ifndef ONLINE_JUDGE
freopen("../in.txt","r",stdin); freopen("../out.txt","w",stdout);
#endif
int T,n;
cin>>T; while(T--){
memset(book,0,sizeof(book));
cin>>n;
for(int i=0;i<n;i++) cin>>a[i];
int max = 0,maxi = -1;
int last = n,now = n;
for(int i=n-1;i>=0;i--){
book[a[i]] = 1;
if(a[i] == now){
put(i,last-1);
last = i;
for(int i=now;i>=0;i--) if(!book[i]){ now = i; break;}
}
}
cout<<"\n";
}
return 0;
}
C. Maximum width
对于字符串s和t的匹配我们可以建立一个前缀和后缀数组,前缀数组记录当前t[i]可以被匹配的前置最小数,后缀数组记录当前t[i]可以被匹配的后置最大数。
然后对于t中的每个字符进行遍历
ans = max(t[i+1] - t[i])
代码:
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
#include<string>
#include<vector>
#include<stack>
#include<bitset>
#include<cstdlib>
#include<cmath>
#include<set>
#include<list>
#include<deque>
#include<map>
#include<queue>
using namespace std;
typedef long long ll;
const double PI = acos(-1.0);
const int INF = 0x3f3f3f3f;
const int maxn = 2e5+5;
int pre[maxn],ord[maxn];
int main(){
std::ios::sync_with_stdio(false);cin.tie(0); cout.tie(0);
#ifndef ONLINE_JUDGE
freopen("../in.txt","r",stdin); freopen("../out.txt","w",stdout);
#endif
int n,m;
string s,t;
cin>>n>>m;
cin>>s>>t;
int now = 0,ans = 0;
for(int i=0;i<n;i++){
if(s[i] == t[now]){
pre[now] = i;
now++;
}
}
now = m-1;
for(int i=n-1;i>=0;i--){
if(s[i] == t[now]){
ord[now] = i;
now--;
}
}
for(int i=0;i<n;i++){
ans = max(ans,ord[i+1]-pre[i]);
}
cout<<ans<<"\n";
return 0;
}
D. Genius’s Gambit
我个人是找到规律完成的这个题,感觉有点剑走偏锋…
因为两个在同位数上只要x和y相等,x-y在此位数上就是0,我们只关注x-y的二进制数中1的个数