Codeforces Round #762 (Div. 3) 全部题解

A. Square String?

#include<bits/stdc++.h>
using namespace std;
int main(){
    int t;
    cin>>t;
    while(t--){
        string s;
        cin>>s;
        if(s.size()%2==1){
            cout<<"NO"<<endl;
            continue;
        }
        
        int flag=0;
        for( int i=0;i<s.size()/2;i++){
            if(s[i]!=s[s.size()/2+i]) flag=1;
        }
        if(flag==0){
            cout<<"YES"<<endl;

        }
        else cout<<"NO"<<endl;
        
    }
}

B. Squares and Cubes

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
int main(){
    int t;
    cin>>t;
    while(t--){
        ll n;
        cin>>n;
        set<ll>se;
        for( ll i=1;i*i*i<=n;i++){
            se.insert(i*i*i);
        }
        for( ll i=1;i*i<=n;i++){
            se.insert(i*i);
        }
        cout<<se.size()<<endl;
    }
    return 0;
}

C. Wrong Addition

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
int main(){
	int t;
	cin>>t;
	while(t--){
		ll a,s;
		cin>>a>>s;
		string ans;
		int flag=0;
		while(s&&a){
			if(s%10>=a%10){
				ans+='0'+s%10-a%10;
				s/=10;
				a/=10;
			}
			else if(s%10<a%10){
				ll ss=s%100;
				if(s%100-a%10>=10||s%100-a%10<0) {
					flag=1;
					break;
				}
				ans+='0'+s%100-a%10;
				a/=10;
				s/=100;
			}
		}
		while(s){
			ans+=s%10+'0';
			s/=10;
		}
		if(a) flag=1;
		reverse(ans.begin(),ans.end());
		ll x=0;
		for( int i=0;i<ans.size();i++){
			x=x*10+ans[i]-'0';
		}
		if(flag) cout<<"-1"<<endl;
		else cout<<x<<endl;
	}
	return 0;
}

D. New Year’s Problem

二分法。
首先二分答案,然后设计check函数
由于题中有一个条件最多选择n-1个商店,所以如果选择商品数大于选择商店数,题目就成立。

#include <bits/stdc++.h>
using namespace std;
const int inf=0x3f3f3f3f;
int solve(){
    int n,k;
    cin>>n>>k;
    vector<vector<int>>v(n,vector<int>(k));

    multiset<pair<int,int>>se[k+1];
    for( int i=0;i<n;i++){
        for( int j=0;j<k;j++){
            cin>>v[i][j];
        }
    }
    auto check=[&] (int x){
        vector<int>joyed(k);
        int cnt=0;
        for( int i=0;i<n;i++){
            int flag=0;
            for( int j=0;j<k;j++){
                if(v[i][j]>=x) joyed[j]++,flag=1;
            }
            if(flag) cnt++;
        }
        for( int i=0;i<k;i++) if(joyed[i]==0) return 0;
        int sum=accumulate(joyed.begin(),joyed.end(),0);
        if(sum>cnt) return 1;
        else return 0;
    };
    int l=0,r=1e9;
    while(l<r){
        int mid=(l+r+1)>>1;
       // cout<<mid<<" "<<check(mid)<<endl;
        if((!check(mid))<1) l=mid;
        else r=mid-1;
    }
    return l;
}
int main() {
    int t;
    cin>>t;
    while(t--){
        cout<<solve()<<endl;
    }
}

E. MEX and Increments

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=200100;
int w[N],cnt[N];
int main(){
	int t;
	cin>>t;
	while(t--){
		int n;
		cin>>n;
		multiset<int>se;
		memset(cnt,0,sizeof(int)*(n+10));
		for( int i=0;i<n;i++){
			scanf("%d",&w[i]);
			cnt[w[i]]++;
		}
		sort(w,w+n);
		ll sum=0;
		int flag=0;//当flag==1时全部是-1
		for( int i=0;i<=n;i++){
			if(flag){
				printf("-1 ");
				continue;
			}
			if(cnt[i]==0) {
				printf("%lld ",sum);
				if(se.size()==0){
					flag=1;
					continue;
				}
				multiset<int> ::iterator it=--se.end();
				if(*it>i) {
					flag=1;
					continue;
				}
				else{
					sum+=i-*it;
					se.erase(--se.end());
				}
			}
			else {
				// sum+=cnt[i];
				printf("%lld ",sum+cnt[i]);
				for( int j=0;j<cnt[i]-1;j++){
					se.insert(i);
				} 
			} 
		}
		printf("\n");
	}
	return 0;
}

F. Let’s Play the Hat?

暴力+贪心
每次取b最小的几个人,放在人多的桌子上玩

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=200100;
int w[N],cnt[N];
struct p{
	int cnt,id;
} b[N];
int cmp( p a,p b){
	return a.cnt<b.cnt;
}
int main(){
	int t;
	cin>>t;
	while(t--){
		int n,m,k;
		scanf("%d%d%d",&n,&m,&k);
		memset(b,0,(n+10)*sizeof(int));
		int low=n/m,high=n/m+(bool)(n%m);
		for( int i=1;i<=n;i++){
			b[i].id=i;
			b[i].cnt=0;
		}
		// cout<<low<<" "<<high<<"??"<<endl;
		if(low==high)
		{
			for( int i=1;i<=k;i++){
				int cnt=1;
				for( int j=1;j<=m;j++){
					printf("%d ",low);
					for( int pp=1;pp<=low;pp++) printf("%d ",cnt++);
				}
				printf("\n");
			}
		}
		else
		{
			int chigh=n-m*low;
			int clow=m-chigh;
			for( int i=1;i<=k;i++){
				sort(b+1,b+1+n,cmp);
				int idx=1;
				for( int j=1;j<=m;j++){
					if(j<=chigh) {
						printf("%d ",high);
						for( int pp=1;pp<=high;pp++) {
							printf("%d ",b[idx++].id );
							b[idx-1].cnt++;
						}
						printf("\n");
					}
					else{
						printf("%d ",low);
						for( int pp=1;pp<=low;pp++){
							printf("%d ",b[idx++].id ); 
						}
						printf("\n");
					}
				}
			}
		}
		printf("\n");
	}
	return 0;
}

G

并查集

#include <bits/stdc++.h>
using namespace std;
const int inf=0x3f3f3f3f;
struct dsu
{
    const int n;
    vector<int>a;
    dsu( int n):n(n+1),a(n+1){
        for( int i=0;i<n+1;i++) a[i]=i;
    }
    //y向x合并
    void unite(int x, int y) {
        a[find(y)] = find(x);
    }
    int find(int u) {
        return a[u] == u ? a[u] : a[u] = find(a[u]);
    }
};

int solve(){
    int n,k;
    int ans=0;
    cin>>n>>k;
    vector<array<int,4> >mine(n);
    vector<int>t(n);
    dsu d(n);
    for( int i=0;i<n;i++){
        for( int j=0;j<3;j++) cin>>mine[i][j];
        mine[i][3]=i;
        t[i]=mine[i][2];
    }
    auto cmp1=[&](array<int,4> a,array<int,4> b){
        if(a[0]!=b[0]) return a[0]<b[0];
        else return a[1]<b[1];
    };
    sort(mine.begin(),mine.end(),cmp1);
    for( int i=1;i<n;i++){
        if(mine[i][0]==mine[i-1][0]&&mine[i][1]-mine[i-1][1]<=k){
            //cout<<mine[i-1][1]-mine[i][1]<<endl;
            int x=mine[i][3],y=mine[i-1][3];
            x=d.find(x),y=d.find(y);
            t[x]=min(t[x],t[y]);
            d.unite(x,y);
        }
    }


    auto cmp2=[&](array<int,4> a,array<int,4> b){
        if(a[1]!=b[1]) return a[1]<b[1];
        else return a[0]<b[0];
    };
    sort(mine.begin(),mine.end(),cmp2);
    for( int i=1;i<n;i++){
        if(mine[i][1]==mine[i-1][1]&&mine[i][0]-mine[i-1][0]<=k){
            int x=mine[i][3],y=mine[i-1][3];
            x=d.find(x),y=d.find(y);
            t[x]=min(t[x],t[y]);
            d.unite(x,y);
        }
    }
    multiset<int>se;
    for( int i=0;i<n;i++){
        if(d.find(i)==i) {
            se.insert(t[i]);
        }
    }
    // for( int i=0;i<v.size();i++){
    //     cout<<v[i].first<<v[i].second<<endl;
    // }

    for( int i=0;i<=200000;i++){
        while(!se.empty()&&*se.begin()==i) se.erase(se.begin());
        if(i+1>=se.size()) return i;
    }
    return -1;
}
int main() {
    int t;
    cin>>t;
    while(t--){
        cout<<solve()<<endl;
    }
}

H. Permutation and Queries

分块算法
由于数列是一个全排列,因此一个点只有唯一的父节点和子节点。
取分块大小为sqrt(n),预处理所有数值跳过一整块的下一个结点。
每次更新,暴力更新前一块和后一块的所有值。
复杂度为(nlogn)

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=100100;
int p[N],child[N];
const int sq=300;
int jump[N];
void update(int x){
	int y=x,z=x;
	for( int i=1;i<=sq;i++) y=p[y];
	for( int i=1;i<=sq;i++) jump[z]=y,z=p[z],y=p[y];
	y=x,z=x;
	for( int i=1;i<=sq;i++) y=child[y];
	for( int i=1;i<=sq;i++) jump[y]=z,z=p[z],y=p[y];
}
int main(){
		int n,q;
		cin>>n>>q;
		for( int i=1;i<=n;i++){
			scanf("%d",&p[i]);
			child[p[i]]=i;
		}

		for( int i=1;i<=n;i++){
			int x=i;
			for( int j=1;j<=sq;j++){
				x=p[x];
			}
			jump[i]=x;
		}
		while(q--){
			int a,b,c;
			scanf("%d%d%d",&a,&b,&c);
			if(a==1){
				swap(child[p[b]],child[p[c]]);
				swap(p[b],p[c]);
				update(b);
				update(c);
			}
			else{
				while(c>=sq){
					b=jump[b];
					c-=sq;
				}
				while(c--){
					b=p[b];
				}
				printf("%d\n",b );
			}
		}
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值