ACDC智能训练 2023-4

B. Little Girl and Game

Codeforces Round 169 (Div. 2)
#博弈游戏
两人轮流删去字符串中的一个字符,如果删去之后,可以重排获得回文字符串,则对方赢。两人都选择最优策略,谁会赢?
重排则不考虑字符顺序,处理所有字符计数。什么样的字符串可以构成回文串?字母计数全是偶数,或者有一个奇数。
如果初始条件如上,那么a赢。
如果有多个奇数呢?ab都会尽量避免白送,不会让对方赢。
比如2 3 3 ->A1 3 3 ->B 0 3 3 ->A 0 2 ->B赢
比如1 1 1 ->A 0 1 1 ->B 0 0 1->A赢
比如 1 1 2->A 1 1 1->…->B赢
偶数没有作用,所有的计数都可以归为0或1。如果有两个以上的奇数,并且计数之和是偶数,那么B赢;如果有两个以上的奇数,并且计数之和是奇数,那么A赢

int cnt[26];
signed main(){
	IOS;
	string s;cin>>s;
	fer(i,0,s.size()){
		cnt[s[i]-'a']++;
	}
	fer(i,0,26){
		if(cnt[i]%2==1){
			if(s.size()%2==1)cout<<"First"<<endl;
			else cout<<"Second"<<endl;
			return 0;
		}
	}
	cout<<"First"<<endl;
	return 0;
}

A. Points on Line

Codeforces Round 153 (Div. 1)
#二分

	IOS;
	int n,d;cin>>n>>d;
	fer(i,0,n)cin>>a[i];
	int cnt=0;
	int l,r;
	fer(i,0,n-2){
		l=i+2;r=n-1;
		while(l<r){
			int mid=(l+r+1)>>1;
			if(a[mid]-a[i]>d)r=mid-1;
			else l=mid;
		}
		if(a[l]-a[i]<=d){
			int tmp=l-i-1;//右端点 
			cnt+=(1+tmp)*tmp/2;
		}
	}
	cout<<cnt<<endl;
	return 0;
}

A. Mocha and Math

Codeforces Round 738 (Div. 2)
#位运算
经过一番操作使得序列的最大值最小
按位与只会让数字越来越小,因此把序列的所有数与一遍就是答案

const int N=105,mod=1e9+7;
int a[N];
signed main(){
	IOS;
	cf{
		int n;cin>>n;
		fer(i,0,n)cin>>a[i];
		int res=a[0];
		fer(i,1,n)res=res&a[i];
		cout<<res<<endl;
	}
	return 0;
}

A. Party

Codeforces Beta Round 87 (Div. 1 Only)
有点像并查集。求多棵树的最大深度
构造树还需要额外的数据结构,这个题n只有2e3,n^2完全可以ac,因此直接简单粗暴遍历一遍

const int N=2e3+1,mod=1e9+7;
int a[N];
signed main(){
	IOS;
	int n;cin>>n;
	fer(i,1,n+1)cin>>a[i];
	int mx=0;
	fer(i,1,n+1){
		int cnt=0;
		int now=i;
		while(a[now]!=-1){
			cnt++;
			now=a[now];
		}
		mx=max(mx,cnt+1);
	}
	cout<<mx;
	return 0;
}

A. Hossam and Combinatorics

#排序
Codeforces Round 837 (Div. 2)
找出多少对差为最大值的i,j
普通情况是cntl*cntr*2
特殊情况是所有数字一样,cnt*(cnt-1)

const int N=1e5+5,mod=1e9+7;
int a[N];
signed main(){
	IOS;
	cf{
		int n;cin>>n;
		fer(i,0,n)cin>>a[i];
		sort(a,a+n);
		int mx=a[n-1]-a[0];
		int cntl=0,cntr=0;
		fer(i,0,n){
			if(a[i]==a[0])cntl++;
			else break;
		}
		for(int i=n-1;i>=cntl;i--){
			if(a[i]==a[n-1])cntr++;
			else break;
		}
		if(cntr==0)cout<<cntl*(cntl-1)<<endl;
		else cout<<cntl*cntr*2<<endl;
		
	}
	return 0;
}

A. Deadline

#数学
Educational Codeforces Round 80 (Rated for Div. 2)
x + d x + 1 x+\frac{d}{x+1} x+x+1d的最小值,类似对勾函数

signed main(){
	IOS;
	cf{
		int n,d;cin>>n>>d;
		int tmp=sqrt(d);
		int mn=1e18;
		fer(i,max((long long)0,tmp-10000),min(d+1,tmp+10000)){
			int res;
			res=i+d/(i+1);
			if(i&&d%(i+1)!=0)res++;
			if(res<=mn)mn=res;
			else break;
		} 
		if(mn<=n)cout<<"YES"<<endl;
		else cout<<"NO"<<endl;
	}
	return 0;
}

B. Spoilt Permutation

#模拟
Codeforces Beta Round 52 (Div. 2)

const int N=1e3+1,mod=1e9+7;
int a[N];
signed main(){
	IOS;
	int n;cin>>n;
	fer(i,0,n)cin>>a[i];
	int i=0;
	for(i;i<n;i++){
		if(a[i]!=i+1)break;
	}
	int l=i+1,r=a[i];
	bool f=1;
	fer(j,i+1,r-1){
		if(a[j]==a[j-1]-1)continue;
		else{
			f=0;break;
		}
	}
	if(f){
		fer(j,r,n){
			if(a[j]!=j+1){
				f=0;break;
			}
		}
	}
	if(f&&l!=n+1)cout<<l<<" "<<r<<endl;
	else cout<<"0 0"<<endl;
	return 0;
}

B - Coloring a Tree

Codeforces Round 453 (Div. 2)
类似并查集。模拟是从根向叶子染,如果和父节点颜色相同,则不需要多染色一次,如果不同,则需要染色。实际上不需要模拟,只需要计数。

int fa[N],c[N];
signed main(){
	IOS;
	int n;cin>>n;
	fa[1]=-1;
	fer(i,2,n+1)cin>>fa[i];
	int cnt=0;
	fer(i,1,n+1){
		cin>>c[i];
		if(c[i]!=c[fa[i]])cnt++;
	}
	cout<<cnt;
	return 0;
}

C. Zero-Sum Prefixes

Codeforces Round 833 (Div. 2)
修改序列中0为任意整数,使得前缀和=0的个数最多
从后往前去处理,如果遇到ai==0,那么处理;如果没遇到,那么把前缀和放进map,以备后用:挑出前缀和个数最多的那个值,用0去抵消
为什么是倒着处理?因为前面抵消了,后面才能出现prefix=0
为什么不管=0的sum?因为要改ai的话sum=0也没用,还是会变。不要考虑现在有几个0,而要考虑怎么能获得最多的0

const int N=2e5+5,mod=1e9+7;
int a[N],sum[N]; 
signed main(){
	IOS;
	cf{
		int n;cin>>n;
		fer(i,1,n+1){
			cin>>a[i];
			sum[i]=sum[i-1]+a[i];
		}
		int cnt=0;
		map<int,int>mp;
		for(int i=n;i>=1;i--){
			mp[sum[i]]++;
			if(!a[i]){
				int mx=0;
				for(auto k:mp)mx=max(mx,k.second);
				cnt+=mx;
				mp.clear();
			}
		}
		cnt+=mp[0];
		cout<<cnt<<endl;
	}
	return 0;
}

F. Vitaly and Advanced Useless Algorithms

#动态规划
Codeforces Round 776 (Div. 3)
对每个任务,挑出最快使得进度到达100的方式

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值