CF Round #531 (Div. 3)

ACM题集:https://codeforces.com/contest/1102
题目链接:https://codeforces.com/blog/entry/64439

A题(略)

#include<bits/stdc++.h>
#define ll long long 
#define fo(i,j,n) for(register int i=j; i<=n; ++i)
using namespace std;
ll n;
int main(){
	cin>>n;
	printf("%lld\n",((n+1)*n/2)%2);
	return 0;
}

B题

题意:给一个数组a,给一个数字k(代表有k种颜色)
对a所有数字进行染色,满足,每种颜色都要用上,使用同一种颜色的数字是不同的
输出染色方案
解法:把数字分开来,使用取模运算使得所有颜色都使用上,且同数字颜色不一样

#include<bits/stdc++.h>
#define ll long long
#define fo(i,j,n) for(register int i=j; i<=n; ++i)
using namespace std;
int n,k,a[5005],mp[5200],idx[5200];
int main(){
	scanf("%d%d",&n,&k);
	fo(i,1,n)scanf("%d",&a[i]),mp[a[i]]++;
	if(k>n){ // 数字太少会使得部分颜色没有被使用 
		printf("NO\n");
	}else{
		fo(i,1,n)if(mp[a[i]]>k){ // 有一种数字超过颜色总数会使得同一个数字使用相同颜色 
			printf("NO\n");
			return 0;
		}
		printf("YES\n");
		fo(i,1,n)idx[i]=i;
		sort(idx+1,idx+1+n,[&](int i, int j){return a[i]<a[j];}); // 按数字大小排序 
		fo(i,1,n){ // 计算颜色,保证所有颜色都被使用到 并且同个数字颜色不同 
			a[idx[i]] = 1+i%k;
		}
		fo(i,1,n)printf("%d ",a[i]);
	}
	return 0;
}

C题(略)

题意:A人破坏物品耐久度x,B人提高物品耐久度y,A先破坏,0耐久度物品不能修补,问最多有多少个耐久度为0(B足够聪明)

#include<bits/stdc++.h>
#define ll long long
#define fo(i,j,n) for(register int i=j; i<=n; ++i)
using namespace std;
int n,x,y,a[100005],num;
void solve(){
	if(x>y){ // 游戏的次数特别大,可以消耗耐久度到完 
		printf("%d\n",n);
	}else{  // 只能破坏掉一半,其他的会被慢慢补回来 
		printf("%d\n",(num+1)/2);
	}
}
int main(){
	scanf("%d%d%d",&n,&x,&y);
	fo(i,1,n)scanf("%d",&a[i]),num+=a[i]<=x;
	solve();
	return 0;
} 

D题

题目:序列012121202....即由012这三个数字组成的序列,
要求更换序列的数字(只能012)使得0,1,2各占总长度1/3,
并且替换次数最少和字典序最小 

if(j<=a[i] || t<=yong[a[i]] && yong[a[i]]<=mp[a[i]])
注意这一行,前面表示优先替换成小的,不适用后面的来替换,后面表示剩下的都是多余的必须得替换掉了

#include<bits/stdc++.h>
#define ll long long
#define fo(i,j,n) for(register int i=j; i<=n; ++i)
using namespace std;

int n,t,a[300006],mp[5],yong[5]; // 使用的 
void solve(){
	t = n/3;
	fo(i,1,n){
		if(mp[a[i]]>t){
			for(int j=0; j<3; ++j){
				if(mp[j]<t){
					if(j<=a[i] || t<=yong[a[i]] && yong[a[i]]<=mp[a[i]]){ //直接更换 或者 a[i]填完后有剩余 
						mp[a[i]]--;
						a[i]=j;
						mp[a[i]]++;
					}
					break;
				} 
			}
		}
		yong[a[i]]++;
	}
	fo(i,1,n)printf("%d",a[i]);
}
int main(){
	scanf("%d",&n);
	fo(i,1,n)scanf("%1d",&a[i]),mp[a[i]]++;
	solve();
	return 0;
} 

E题

E题:题目大意就是要你找出有多少个完全没有交集的块,然后算2的幂
	[(]) 这样算交集算一块1 2 2 3 1 3 4 4 这样算两块122313一块44一块
	先把每个数字的左右区间算出来,再计算有多少个块即可 
#include<bits/stdc++.h>
#define ll long long
#define fo(i,j,n) for(register int i=j; i<=n; ++i)
using namespace std;
const int mod = 998244353;
int n,a[200006],b[200006],c[200006],mi[200005],mx[200005];
ll qpow(ll a, ll n){ // 类型一定要一样 long long 
	ll ans = 1;
	while(n){
		if(n&1) ans = (ans*a)%mod;
		a = a*a%mod;
		n>>=1;
	}
	return ans%mod;
}
ll ans = 1;
void solve(){
	// 算mi,mx 
	fo(i,1,n){
		if(!mi[c[i]])mi[c[i]]=i;
		mx[c[i]]=i; 
	}
	// 合并有交集的区间,计算一共有多少个区间 
	int num = 0;
	for(int i=1; i<=n; i++){
		num++;
		int t=mx[c[i]];
		for(int j=mi[c[i]]; j<=t; ++j){
			if(mx[c[j]]>t)t=mx[c[j]];
		}
		i=t;
	}
	printf("%I64d\n",qpow(2,num-1));
}
int main(){
	scanf("%d",&n);
	fo(i,1,n){
		scanf("%d",&a[i]);
		b[i]=i;
	}
	// 离散化 
	sort(b+1,b+1+n,[&](int i,int j){return a[i]<a[j];});
	c[b[1]]=1;
	fo(i,2,n){
		if(a[b[i]]==a[b[i-1]])c[b[i]]=c[b[i-1]];
		else c[b[i]]=c[b[i-1]]+1;
	}
	solve();
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值