Codeforces Round #827 (Div. 4)A~G(模拟,暴力,前缀最大值,二分,二进制)

签到题A~C

A

#include<bits/stdc++.h>
using namespace std;
int n,w,x,y;int a[100005],b[100005];
int main()
{
    int T=1;cin>>T;
    while(T--){
     cin>>w>>x>>y;
     if(w==x+y)cout<<"YES\n";
     else if(x==w+y)cout<<"YES\n";
     else if(y==x+w)cout<<"YES\n";
     else cout<<"NO\n";
    }
    return 0;
}

B

#include<bits/stdc++.h>
using namespace std;
int n,w,x,y;int a[100005],b[100005];
int main()
{
    int T=1;cin>>T;
    while(T--){
     cin>>n;
     for(int i=1;i<=n;i++)cin>>a[i];
     sort(a+1,a+1+n);bool flag=0;
     for(int i=1;i<n;i++)
        if(a[i]==a[i+1])flag=1;
     if(flag)cout<<"NO\n";
     else cout<<"YES\n";
    }
    return 0;
}

C

#include<bits/stdc++.h>
using namespace std;
int main()
{
    int T=1;cin>>T;
    while(T--){
int n,w,x,y;int a[10]={0},b[10]={0};char mp[10][10];
        for(int j=1;j<=8;j++)
        for(int i=1;i<=8;i++)cin>>mp[j][i];
        for(int ii=1;ii<=8;ii++){
            bool flag=0;
            for(int i=1;i<=8;i++){
                if(mp[ii][i]!='R')flag=1;
            }
            if(!flag)a[ii]=1;
        }
        for(int ii=1;ii<=8;ii++){
            bool flag=0;
            for(int i=1;i<=8;i++){
                if(mp[i][ii]!='B')flag=1;
            }
            if(!flag)b[ii]=1;
        }
        for(int i=1;i<=8;i++){
            if(a[i]){cout<<"R\n";break;}
            if(b[i]){cout<<"B\n";break;}
        }

    }
    return 0;
}

D. Coprime

题意:给一个数列,如果a[i]和a[j]互质,那么i+j。求最大的i+j

错误:比赛的时候我把所有答案都存在vector里面了,结果MLE了,回过神来发现只要max就可以了,结果因为n平方的复杂度TLE了

思路:赛后发现虽然n有2e5,但是a的范围只有1~1000,所以可以记录下每个a[i]的最大序号,在循环1e6次就能做完了

代码:

#include<bits/stdc++.h>
using namespace std;
int a[200005]={0};int n;int vis[1003];
signed main()
{
    ios::sync_with_stdio(0);cin.tie(0);
    int T=1;cin>>T;
    while(T--){
        memset(vis,0,sizeof(vis)); int maxx=-1;
        cin>>n;
        for(int i=1;i<=n;i++)cin>>a[i];
        for(int i=1;i<=n;i++)vis[a[i]]=i;
        for(int i=1;i<=1000;i++){
            for(int j=i;j<=1000;j++){
                if(!vis[i]||!vis[j])continue;
                if(__gcd(i,j)==1)maxx=max(maxx,vis[i]+vis[j]);
            }
        }
        cout<<maxx<<'\n';
    }
    return 0;
}

E. Scuza

题意:已知腿长,走楼梯,直到楼梯高度大于腿长,不走了,求已经走过的高度

扫描二维码关注公众号,回复: 15892280 查看本文章

错误:比赛的时候写双重循环,TLE了;想到了前缀和,没有想过前缀最大值;想过了二分查找,但觉得没有次序就没接着想了

思路:前缀最大值+二分查找

lower_bound() 函数查找[first, last)区域中不小于val的第一个元素。

upper_bound() 查找[first, last)区域中第一个大于 val 的元素。

#include<bits/stdc++.h>
using namespace std;
#define int long long
int n,m,w,x,y;int a[200005],k,sum[200005],maxx[200005]={0};
signed main()
{
    int T=1;cin>>T;
    while(T--){
        cin>>n>>m;
        for(int i=1;i<=n;i++){
            cin>>a[i];sum[i]=sum[i-1]+a[i];maxx[i]=max(maxx[i-1],a[i]);
        }
        for(int i=1;i<=m;i++){
            cin>>k;
            int x=upper_bound(maxx+1,maxx+n+1,k)-maxx;
            cout<<sum[x-1]<<' ';
        }
        cout<<'\n';
    }
    return 0;
}

F. Smaller

读错题了orz 反正就是挺简单的一道题      

记得开long long

代码:

#include<bits/stdc++.h>
using namespace std;
#define int long long
int n,w,x,y;
signed main()
{
    int T=1;cin>>T;
    while(T--){
      cin>>n;int suma=1,sumb=1;int a=1,b=1;
      for(int i=1;i<=n;i++){
        int d,k;cin>>d>>k;string ss;cin>>ss;
        if(d==1)for(int p=0;p<ss.size();p++)if(ss[p]=='a')a+=k,suma+=k;
        if(d==2)for(int p=0;p<ss.size();p++)if(ss[p]=='a')b+=k,sumb+=k;
        if(b!=sumb)cout<<"YES\n";
        else if(a==suma){
               if(suma<sumb)cout<<"YES\n";
               else cout<<"NO\n";
        }
        else cout<<"NO\n";
        //a和b都是a,但是a的个数比b少
        //a不都是a,但b都是a,失败
        //b不都是a,成功
      }
    }
    return 0;
}

G. Orray

做的时候总是习惯把数字拆开来做,但好像这种题都是找一个数异或 or 或,然后看情况做

思路:把所有数都遍历一遍,最后找到最优的结果输出

注意:如果把a|b放在if的条件里判断大小,记得加括号

代码:

#include<bits/stdc++.h>
using namespace std;
int a[200005];
bool vis[200005];
int main()
{
    int T;cin>>T;
    while(T--){
        memset(vis,0,sizeof(vis));
        int n;cin>>n;
        for(int i=1;i<=n;i++)cin>>a[i];
        int now=0,mx=0;
        for(int i=1;i<=min(31,n);i++){
            int id=0;
            for(int j=1;j<=n;j++){
                if((now|a[j])>mx){
                   mx=now|a[j];id=j;
                }
            }
            if(id==0)break;
            now=mx;vis[id]=1;cout<<a[id]<<' ';
        }
        for(int i=1;i<=n;i++){
            if(vis[i]==0)cout<<a[i]<<' ';
        }
        cout<<'\n';
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/zy98zy998/article/details/127320378
今日推荐