codeforces #704 div2(4/5)

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的个数

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值