Codeforces Round 866 (Div. 2) 题解

总结:4.20晚在宿舍V了一场,第二题卡住了,最后才交上,发现是没开long long,因为开始没有往那方面想嘛。。。。

A. Yura's New Name  

思路:定义一个f来表示是否遇到“^”,每遇到一个“_”判断前面是否有“^”,即f是否为1,若不为1则添加一个“^”,同时使f为0,注意需要特判最后一个为“_”或者只有一个“^”的情况!!!

#include<iostream>
using namespace std;

int main(){
	int T,ans;
	string s;
	cin>>T;
	while(T--){
		int f=0;
		ans=0;
		cin>>s;
		for(int i=0;i<s.size();i++){
			if(s[i]=='_'){
				if(!f){
					ans++;
				}
				if(i==s.size()-1){
					ans++;
				}
				f=0;
			}else{
				f=1;
				if(s.size()==1){
					ans++;
				}
			}
		}
		cout<<ans<<'\n';
	}
}

B. JoJo's Incredible Adventures

不开long long见祖宗,没想到这个题会爆int,被坑惨了,应该是存在2e5*2e5的问题。。。

思路:可以说是找规律吧。。。遍历两遍字符串s(因为s是成环的),计算最长的1字串的长度,同时还要考虑字符串全为1的情况,下面的计算面积就是找规律了,分就来讨论,具体规律就不说了,看代码即可

#include<iostream>
#define int long long
using namespace std;

signed main(){
	int T,nmax,ant;
	string s;
	cin>>T;
	while(T--){
		nmax=0;ant=0;
		cin>>s;
		for(int i=0;i<s.size();i++){
			if(s[i]=='1'){
				ant++;
			}else{
				nmax=max(nmax,ant);
				ant=0;
			}
		}
		for(int i=0;i<s.size();i++){
			if(s[i]=='1'){
				ant++;
			}else{
				nmax=max(nmax,ant);
				break;
			}
		}
		ant/=2;
		if(ant!=s.size()){
			if(nmax%2){
				cout<<(nmax+1)/2*(nmax+1)/2<<'\n';
			}else{
				cout<<(nmax/2)*(nmax/2+1)<<'\n';
			}
		}else{
			cout<<ant*ant<<'\n';
		}
	}
	return 0;
}

C. Constructive Problem

思路:可以说是一道思维题吧,输入每个数并用map计数,先逐个遍历找出最小未出现的数记为t,再看是否存在t+1,因为要经过操作使最小未出现的数变为t+1,所以要将t+1全部变为t,即将第一个和最后一个t+1及之间的数全部变为t,若不存在t+1,只需要在小于t且个数大于2或者大于t的数中选一个变为t即可

#include<iostream>
#include<map>
#define int long long
using namespace std;

const int N=200005;
int a[N];
map<int,int>mp;
signed main(){
	int T,n,t;
	cin>>T;
	while(T--){
		bool f=0;
		mp.clear();
		cin>>n;
		for(int i=0;i<n;i++){
			cin>>a[i];
			mp[a[i]]++;
		}
		for(int i=0;i<=N;i++){
			if(!mp[i]){
				t=i;
				break;
			}
		}
		if(mp[t+1]){
			for(int i=0;i<n;i++){
				if(a[i]==t+1){
					int j=i;
					while(mp[t+1]){
						mp[a[j]]--;
						a[j]=t;
						j++;
						mp[t]++;
					}
					break;
				}
			}
		}else{
			for(int i=0;i<n;i++){
				if(a[i]<t&&mp[a[i]]>=2){
					a[i]=t;
					mp[t]=1;
					break;
				}
				if(a[i]>t&&mp[a[i]]){
					a[i]=t;
					mp[t]=1;
					break;
				}
			} 
		}
		if(mp[t+1]){
			f=1;
		}
		for(int i=0;i<=t;i++){
			if(!mp[i]){
				f=1;
				break;
			}
		}
		if(f){
			cout<<"NO"<<'\n';
		}else{
			cout<<"YES"<<'\n';
		}
	}
	return 0;
}

  • 3
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

古谷彻

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值