CF1530

CF1530

A:

序列中最大值,输出即可。

#include<bits/stdc++.h>
using namespace std;
int T; char s[15];
int main(){
    cin>>T;
    while(T--){
        scanf("%s",s+1);  int len=strlen(s+1),ans=0;
        for(int i=1;i<=len;i++) ans=max(ans,s[i]-'0');
        cout<<ans<<endl;
    }
    // system("pause");
    return 0;
}

B:

可以通过一个简单的证明说明在第一个格子放是最优解。

因此我们依次枚举填的情况,这样一定是最优的。

上下两行奇数位全填,左右两列从 \(3\)\(h−2\) 奇数位全填

#include<bits/stdc++.h>
using namespace std;
int T,n,m,a[30][30];
int main(){
    cin>>T;
    while(T--){
        cin>>n>>m;  memset(a,0,sizeof(a));
        for(int i=1;i<=m;i++) if(i&1) a[1][i]=a[n][i]=1;
		for(int i=3;i<=n-2;i++)	if(i&1) a[i][1]=a[i][m]=1;
		for(int i=1;i<=n;i++){ for(int j=1;j<=m;j++) cout<<a[i][j];
			cout<<endl;
		}
    }
    // system("pause");
    return 0;
}

C:

贪心考虑:

如果我们继续有分,那么自己的分数一定是100,伊利亚分数一定是0.

我们使用桶排序

每一阶段,“我”的 100 分获得次数加 1,伊利亚的 0 分获得次数加 1。

然后求出总分,达到目标即可输出,时间复杂度比较优秀。

#include<bits/stdc++.h>
using namespace std;
int T,n;
int get_result(int tong[101],int n){
	int num=n-n/4;//需要计入总分的阶段数。
    int ans=0;
	for(int i=100;i>=0;i--){
		if(tong[i]<=num)ans+=i*tong[i],num-=tong[i];
		else{
			ans+=num*i; break;}
	}
	return ans;
}
int main()
{
	scanf("%d",&T);
	while(T--){
		scanf("%d",&n);
		int tong1[101],tong2[101];
		memset(tong1,0,sizeof(tong1));
		memset(tong2,0,sizeof(tong2));
		int input;
		for(int i=1;i<=n;i++)	scanf("%d",&input),	tong1[input]++;
		for(int i=1;i<=n;i++)  scanf("%d",&input),	tong2[input]++;
		int result1=get_result(tong1,n),result2=get_result(tong2,n);//先算一遍总分。
		if(result1>=result2){
			printf("0\n");
			continue;
		}
		for(int i=n+1;;i++){
			tong1[100]++;
			tong2[0]++;
			result1=get_result(tong1,i);
			result2=get_result(tong2,i);
			if(result1>=result2){
				printf("%d\n",i-n);
				break;
			}
		}
	}
    // system("pause");
	return 0;
}

D:

答案为 \(b_i\) 中不同数字的个数,我们考虑如何构造。

首先,我们把图建出来,每个点连向它要送礼物的人,我们会发现最终的答案中这个图由若干个环组成,切环的大小不能为 \(1\)

那么,我们可以让对于每个点 \(i\) 任意一个在题目中想送 \(i\) 礼物的人向 \(i\) 连边,这样答案就保证了。

我们考虑剩下的,我们让入度为 \(1\),出度为 \(0\) 的点,连向它所在的链的最后方构成环,由于入度和出度都不超过 \(1\),所有非常好维护。

还有的点是入度和出度都为 \(0\) 的。如果这样的点数量为 \(0\) 不需要任何操作;如果这样的点数量为 \(>1\),则连成一个环;如果数量为 \(1\),我们就让这个点强行加入这个图中。

#include<bits/stdc++.h>
using namespace std;
const int N=2e5+5;
int a[N],ans[N],h[N],l[N],T,n;
int get(int x){
    if(!h[x]) return x;
    return h[x]=get(h[x]);
}
int main(){
    cin>>T;
    while(T--){
        scanf("%d",&n); int s=0;vector<int> v;
        for(int i=1;i<=n;i++) h[i]=ans[i]=0;
        for(int i=1;i<=n;i++){
            scanf("%d",&a[i]); 
            if(!h[a[i]]) s++,h[a[i]]=l[a[i]]=i,ans[i]=a[i];
        }
        for(int i=1;i<=n;i++) if(!ans[i]){
            if(get(i)!=i) ans[i]=get(i);
            else v.push_back(i);
        }
        if(v.size()==1) ans[v[0]]=a[v[0]],ans[l[a[v[0]]]]=v[0];
        else{
            if(v.size()){ int m=v.size()-1;
                for(int i=0;i<m;i++) ans[v[i]]=v[i+1];
                ans[v[m]]=v[0];
            }
        }
        cout<<s<<endl; for(int i=1;i<=n;i++) printf("%d ",ans[i]); puts("");
    }
    // system("pause");
    return 0;
}
posted @ 2021-09-02 16:46  Evitagen  阅读(39)  评论(0编辑  收藏  举报