Codeforces round #764 ABCDG

文章目录

A

最大值减最小值

#include<bits/stdc++.h>
using namespace std;
int main(){
    int t;
    cin>>t;
    while(t--){
        int minn=0x3f3f3f3f,maxn=0;
        int n;
        cin>>n;
        for( int i=1;i<=n;i++){
            int x;
            cin>>x;
            minn=min(x,minn);
            maxn=max(x,maxn);
        }
        cout<<maxn-minn<<endl;
    }
    return 0;
}

B

分类讨论公差的三种情况

#include<bits/stdc++.h>
using namespace std;

int solve(){
    int a,b,c;
    cin>>a>>b>>c;
    if(a+c==b+b) return 1;
    if((b+b-c)%a==0&&b+b-c>0) return 1;
    if((a+c)%(b*2)==0) return 1;
    if((b+b-a)%c==0&&b+b-a>0) return 1;
    return 0;
}
int main(){
    int t;
    cin>>t;
    while(t--){
        if(solve()){
            cout<<"YES"<<endl;
        }
        else cout<<"NO"<<endl;
    }
    return 0;
}

C

由于每个数都是单调递减的,需要从大到小维护,使用set,每次取出最大值,看是否符合题意。

#include<bits/stdc++.h>
using namespace std;

int solve(){
    int n;
    cin>>n;
    multiset<int,greater<int> >se;
    for( int i=1;i<=n;i++){
        int x;
        cin>>x;
        se.insert(x);
    }
    for( int i=n;i>=1;i--){
        while(*se.begin()>i){
            int x=*se.begin();
            se.erase(se.begin());
            x/=2;
            se.insert(x);
        }
        if(*se.begin()!=i) return 0;
        else se.erase(se.begin());
    }
    return 1;
}
int main(){
    int t;
    cin>>t;
    while(t--){
        if(solve()){
            cout<<"YES"<<endl;
        }
        else cout<<"NO"<<endl;
    }
    return 0;
}

D

模拟
分类讨论,一个镜像串中的字母,只能由一个字母是奇数。
然后将奇数的字母分配给每个串。

#include<bits/stdc++.h>
using namespace std;
int cnt[30];
int solve(){
    memset(cnt,0,sizeof(cnt));
    int n,k;
    cin>>n>>k;
    string s;
    cin>>s;
    int res=0;
    for( int i=0;i<s.size();i++){
        cnt[s[i]-'a']++;
    }
    int c=0;
    for( int i=0;i<=26;i++){
        if(cnt[i]%2==1) c++;
    }
    if(c>=k){
        res=1;
        n-=c;
        res+=n/2/k*2;
    }
    else {
        n-=c;
        res+=n/2/k*2;
        n-=res*k;
        if(c+n>=k) res++;
    }
    return res;
    return (n)/k;
}
int main(){
    int t;
    cin>>t;
    while(t--){
        cout<<solve()<<endl;
    }
    return 0;
}

G

位运算,贪心算法,数据结构
int范围内的数最多有31位,将每个数字按位拆开,然后存储在vector中。
从最高位向最低位遍历,尝试删除每个位上的数,如果删除后图依然连通,那么就可以删除,如果删除后图不能连通,就把删除的边重新加回图中。
注意用set维护会超时

#include<bits/stdc++.h>
using namespace std;
const int N=200100;
int h[N],ne[N+N],to[N+N],val[N+N],cnt;
int del[N+N];//记录某个边是否被删除
vector<int>edge[35];
void add( int a,int b,int c){
    int pos=0;
    while(1ll<<pos <= c){
        if((c&(1ll<<pos))!=0 ) edge[pos].push_back(cnt);
        pos++;
    }
    del[cnt]=0;
    to[cnt]=b,val[cnt]=c,ne[cnt]=h[a],h[a]=cnt++;
}
int n,m;

int vis[N];
int dfs( int rt,int pos){//返回遍历的点的个数
    // cout<<rt<<endl;
    vis[rt]=1;
    int res=1;
    for( int i=h[rt];i!=-1;i=ne[i]){
        int j=to[i];
        if(del[i]||vis[j]==1) continue;
        // if(edge[pos].find(i)!=edge[pos].end()) continue;
        res+=dfs(j,pos);
    }    
    return res;
}
int main(){
    int t;
    cin>>t;
    while(t--){
        scanf("%d%d",&n,&m);
        memset(h,-1,(n+10)*sizeof(int));
        for( int i=0;i<34;i++){
            edge[i].clear();
        }        
        for( int i=1;i<=m;i++){
            int a,b,c;
            scanf("%d%d%d",&a,&b,&c);
            add(a,b,c),add(b,a,c);
        }
        int ans=0;
        for( int i=34;i>=0;i--){
            
            if(edge[i].empty()) continue;
            memset(vis,0,sizeof(int)*(n+1));
                // for( set<int>::iterator it=edge[i].begin();it!=edge[i].end();++it){
                //     del[*it]++;
                // }          
            for( int j=0;j<edge[i].size();j++){
                del[edge[i][j]]++;
            }  
            if(dfs(1,i)==n) {

            }
            else{
                ans|=1<<i;
                // for( set<int>::iterator it=edge[i].begin();it!=edge[i].end();++it){
                //     del[*it]--;
                // }
                for( int j=0;j<edge[i].size();j++){
                    del[edge[i][j]]--;
                }  
            }
        }
        printf("%d\n",ans);
    }
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值