ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

CodeTon Round 2 (Div. 1 + Div. 2, Rated, Prizes!)

2022-08-01 15:33:59  阅读:171  来源: 互联网

标签:cnt Rated int rep cin MAXN Prizes solve Div


\(\texttt{Rating Change:}\color{orange}{2213}\color{black}\to \color{orange}{2225}\)
\(\Delta={\color{green}{\texttt{12}}}\qquad \texttt{rank:510}\)

最近质量最高的一场 Chinese Round 吧。

A

可以转化成每次将前面两个中选一个留下。这样也就是说只有 \(b\) 的第一位可以和 \(a\) 相应的后缀不同。并且如果不同必须要是 \(a\) 此前出现过的。

My Code
using namespace std;
const int MAXN=55;
void solve(){
	int n,m;cin>>n>>m;string a,b;
	cin>>a>>b;a=' '+a;b=' '+b;
	int ta=n,tb=m;
	while(a[ta]==b[tb]&&tb>=1) ta--,tb--;
	if(tb>1) cout<<"NO\n";
	else if(tb==0) cout<<"YES\n";
	else{
		per(i,ta,1) if(a[i]==b[1]){
			cout<<"YES\n";
			return;
		}cout<<"NO\n";
	}
}
signed main()
{
	ios::sync_with_stdio(0);
	cin.tie(0);cout.tie(0);
	int T;for(cin>>T;T--;)solve();
	return 0;
}

B

一开始确定一个可选的 \(v\) 的区间,然后将这个区间不停地加上当前的限制。直到区间为空的时候,使用一次 change,然后继续这样做,显然是最少的。

My Code
#define int long long
using namespace std;
const int MAXN=2e5+10;
int a[MAXN];
void solve(){
	int n,x;cin>>n>>x;
	rep(i,1,n) cin>>a[i];
	int l=a[1]-x,r=a[1]+x,ans=0;
	rep(i,2,n){
		if((a[i]-x>=l&&a[i]-x<=r)||(a[i]-x<l&&a[i]+x>=l))
			l=max(l,a[i]-x),r=min(r,a[i]+x);
		else ans++,l=a[i]-x,r=a[i]+x;
	}cout<<ans<<'\n';
}
signed main()
{
	ios::sync_with_stdio(0);
	cin.tie(0);cout.tie(0);
	int T;for(cin>>T;T--;)solve();
	return 0;
}

C

相当于每次我们可以把一处感染堵上。这样我们把所有未感染的段全部取出来,从大到小贪心地去堵。实在太短,已经被感染的就摆,这样肯定能最大限度地救人。

My Code
#define int long long
using namespace std;
const int MAXN=1e5+10;
int a[MAXN];
void solve(){
	int n,m;cin>>n>>m;
	rep(i,1,m) cin>>a[i];
	sort(a+1,a+1+m);
	vector<int> cnt;
	rep(i,2,m) cnt.pb(a[i]-a[i-1]-1);
	cnt.pb(a[1]+n-a[m]-1);
	sort(all(cnt));reverse(all(cnt));
	int del=0,alv=0;
	for(int v:cnt){
		if(v-del>1) alv+=v-del-1,del+=4;
		else if(v-del==1) del+=2,alv++;
		else break;
	}cout<<n-alv<<'\n';cerr<<'\n';
}
signed main()
{
	ios::sync_with_stdio(0);
	cin.tie(0);cout.tie(0);
	int T;for(cin>>T;T--;)solve();
	return 0;
}

D

挺智慧的题。考虑操作一和操作二的不同之处。如果我们对于每个数组构造一个键值:

\[s_i=\sum_{j=1}^m c_{i,j}\times j \]

这样子对于操作一键值是不变的,而操作二会加一。所以我们直接算出每个数组的 \(s\),取最大的,然后与其他的差就是最少的操作二的次数。

My Code
using namespace std;
const int MAXN=1e5+10;
unsigned ll a[MAXN];
void solve(){
	int n,m,x,mxid=0;cin>>n>>m;
	unsigned ll mx=0;
	rep(i,1,n){
		a[i]=0;
		rep(j,1,m)
			cin>>x,a[i]+=1ll*x*j;
		if(a[i]>mx) mx=a[i],mxid=i;
	}cout<<mxid<<' '<<a[mxid]-a[mxid==1?2:1]<<'\n';
}
signed main()
{
	ios::sync_with_stdio(0);
	cin.tie(0);cout.tie(0);
	int T;for(cin>>T;T--;)solve();
	return 0;
}

E

半路改题面差评。

发现如果每个点没有一个后继是 \(0\) 的话,就不会出现减一的点集变化或者加一的点集变化的情况。那我们就可以直接对每个点算贡献。

此时并不一定满足。但是我们可以发现,先暴力跑 \(n\) 次,可以使得这张图满足上述条件,就做完了。

My Code
#define int long long
using namespace std;
const int MAXN=1010;
const int MOD=998244353;
vector<int> e[MAXN],fr[MAXN];
int v[MAXN],cnt[MAXN],deg[MAXN];
void solve(){
	int n,m;cin>>n>>m;
	rep(i,1,n) cin>>v[i],e[i].clear(),fr[i].clear(),cnt[i]=deg[i]=0;
	rep(i,1,m){
		int x,y;cin>>x>>y;
		e[x].pb(y);fr[y].pb(x);deg[x]++;
	}
	int ed=0;
	rep(i,1,n) if(!siz(e[i])){ed=i;break;}
	rep(Cnt,1,1000){
		vector<int> x;
		rep(i,1,n) if(v[i]) x.pb(i);
		if(!siz(x)){
			cout<<Cnt-1<<'\n';
			return;
		}for(int i:x){
			v[i]--;
			for(int s:e[i])
				v[s]++;
		}
	}
	queue<int> q;q.push(ed);cnt[ed]=1;
	while(!q.empty()){
		int x=q.front();q.pop();
		for(int s:fr[x]) (cnt[s]+=cnt[x])%=MOD;
		for(int s:fr[x])
			if(--deg[s]==0)
				q.push(s);
	}
	int ans=1000;
	rep(i,1,n){
		ans=(ans+cnt[i]*v[i]%MOD)%MOD;
	}cout<<ans<<'\n';
}
signed main()
{
	ios::sync_with_stdio(0);
	cin.tie(0);cout.tie(0);
	int T;for(cin>>T;T--;)solve();
	return 0;
}

F

博弈论是我不会的东西。

首先可以发现如果 RB 数量不相等,那么肯定是多的那一方赢了。因为起初两方肯定取 RB 或者 BR。当没有红蓝相邻的时候,只能取自己的那种颜色了。此时就是谁多谁活得久。

所以现在只需要讨论一下两者颜色相同的情况。我们把每一段红蓝相间的拉出来,我们只需要考虑这些段的胜负即可。

利用 \(SG\) 函数和,令 \(SG(len)\) 表示长度为 \(len\) 的红蓝段的 \(SG\) 值。这样直接求是 \(O(n^2)\) 的。然后打表发现实际上在长度很长的时候是以 \(34\) 为一循环的,所以只要预处理前一段即可。

My Code
using namespace std;
const int MAXN=5e5+10;
int sg[155],ha[155];
void init(){
	rep(i,2,150){
		memset(ha,0,sizeof(ha));
		rep(j,1,i-1) ha[sg[j-1]^sg[i-j-1]]=1;
		while(ha[sg[i]]) sg[i]++;
	}
}
void solve(){
	int n;cin>>n;
	string s;cin>>s;s=' '+s;
	int cntr=0,cntb=0,ans=0;
	rep(i,1,n) if(s[i]=='R') cntr++;else cntb++;
	for(int l=1,r;l<=n;l=r){
		r=l+1;while(r<=n&&s[r]!=s[r-1]) r++;
		if(r==l+1) continue;
		int tmp=r-l;
		while(tmp>150) tmp-=34;
		ans^=sg[tmp];
	}
	if(cntr>cntb||(cntr==cntb&&ans))
		cout<<"Alice\n";
	else cout<<"Bob\n";
}
signed main()
{
	ios::sync_with_stdio(0);
	cin.tie(0);cout.tie(0);
	init();
	int T;for(cin>>T;T--;)solve();
	return 0;
}

标签:cnt,Rated,int,rep,cin,MAXN,Prizes,solve,Div
来源: https://www.cnblogs.com/ZCETHAN/p/16540468.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有