牛客周赛34(A~E)

A

两种情况

  1. 两个字符相同只有2
  2. 两个字符不相同4
#include <bits/stdc++.h>
#define int long long
#define rep(i,a,b) for(int i = (a); i <= (b); ++i)
#define fep(i,a,b) for(int i = (a); i >= (b); --i)
#define pii pair<int, int>
#define pdd pair<double,double>
#define ll long long
#define db double
#define endl '\n'
#define x first
#define y second
#define pb push_back
#define vi vector<int>


using namespace std;

void solve() {
	string a,b;
	cin>>a>>b;
	if(a==b){
		cout<<2<<endl;
		cout<<a<<endl;
		cout<<a<<a<<endl;
	}else{
		cout<<4<<endl;
		cout<<a<<endl;
		cout<<b<<endl;
		cout<<a<<b<<endl;
		cout<<b<<a<<endl;
	}
}

signed main() {
	ios::sync_with_stdio(false);
	cin.tie(0);
	cout.tie(0);
//	freopen("1.in", "r", stdin);
	int _;
//	cin>>_;
//	while(_--)
	solve();
	return 0;
}

B

答案只有两种情况0和1
如果已经不是排列答案是0
否则一定可以通过修改一个数变为非排列

#include <bits/stdc++.h>
#define int long long
#define rep(i,a,b) for(int i = (a); i <= (b); ++i)
#define fep(i,a,b) for(int i = (a); i >= (b); --i)
#define pii pair<int, int>
#define pdd pair<double,double>
#define ll long long
#define db double
#define endl '\n'
#define x first
#define y second
#define pb push_back
#define vi vector<int>


using namespace std;

void solve() {
	int n;
	cin>>n;
	set<int>s;
	bool st=false;
	rep(i,1,n){
		int val;
		cin>>val;
		if(s.count(val)!=0||val>n||val<1){
			st=true;
		}
		s.insert(val);
	}
	if(st){
		cout<<0<<endl;
	}else{
		cout<<1<<endl;
		cout<<1<<' '<<n+1<<endl;
	}
}

signed main() {
	ios::sync_with_stdio(false);
	cin.tie(0);
	cout.tie(0);
//	freopen("1.in", "r", stdin);
	int _;
//	cin>>_;
//	while(_--)
	solve();
	return 0;
}

C

从高位往低位贪心,如果是偶数,就分开。
最后需要注意一下用 v e c t o r vector vector排序 s t r i n g string string如何按字典序排序

#include <bits/stdc++.h>
#define int long long
#define rep(i,a,b) for(int i = (a); i <= (b); ++i)
#define fep(i,a,b) for(int i = (a); i >= (b); --i)
#define pii pair<int, int>
#define pdd pair<double,double>
#define ll long long
#define db double
#define endl '\n'
#define x first
#define y second
#define pb push_back
#define vi vector<int>


using namespace std;

bool cmp(string a, string b) {
	if(a.size()!=b.size())	return a.size()<b.size();
	return a+b < b+a; //按字典序从小到大排列
}

void solve() {
	string s;
	cin>>s;
	int n=s.size()-1;
	vector<string>ans;
	int cur=0;
	rep(i,0,n){
		int c=s[i]-'0';
//		cout<<c<<endl;
		string res;
		if(c%2==0){
			rep(j,cur,i){
				res+=s[j];
			}
			ans.pb(res);
			cur=i+1;
		}
	}
	sort(ans.begin(),ans.end(),cmp);
	for(auto it:ans){
		cout<<it<<endl;
	}
}

signed main() {
	ios::sync_with_stdio(false);
	cin.tie(0);
	cout.tie(0);
//	freopen("1.in", "r", stdin);
	int _;
//	cin>>_;
//	while(_--)
	solve();
	return 0;
}

D

这道分类讨论刚开始写的很乱感觉有点不好写,确实不太好写
参考了qfl的代码感觉用队列写确实简洁了很多。
分类讨论
首先通过观察我们可以知道,如果有答案最后的答案,一定是前面一段全部是一样的,后面一段全部是一样的。
也就是 a a a a b b b b aaaabbbb aaaabbbb这种形式
我们可以通过把每一个0变为离他最近的非零数字,然后去check是否合法,来判断和构造解。
那种情况是可能合法的。
a n s ans ans:我们用 a n s ans ans来表示相邻项的差的绝对值
a n s > 1 ans>1 ans>1:一定不合法
a n s = 1 ans=1 ans=1:合法,且经过暴力修改得到的解就是构造方案
a n s = 0 ans=0 ans=0:需要去看 a [ 1 ] a[1] a[1]或者 a [ n ] a[n] a[n],是否能产生1的贡献。
为什么考虑 1 、 n 1、n 1n因为1个数出现在中间的话一定会产生2的贡献
如果 a [ 1 ] a[1] a[1] a [ n ] a[n] a[n]有一个在最开始为0则有解,如果同时都不为0则无解,
有解的话,在修改完的 a [ 1 ] 或 a [ n ] a[1]或a[n] a[1]a[n]上加1就是构造的解。

#define int long long
#define rep(i,a,b) for(int i = (a); i <= (b); ++i)
#define fep(i,a,b) for(int i = (a); i >= (b); --i)
#define pii pair<int, int>
#define pdd pair<double,double>
#define ll long long
#define db double
#define endl '\n'
#define x first
#define y second
#define pb push_back
#define vi vector<int>

using namespace std;
const int maxn=1e5+10;
int n;
int a[maxn],vis[maxn];

void solve() {
	cin>>n;
	queue<int>q;
	rep(i,1,n){
		cin>>a[i];
		if(a[i]){
			q.push(i);
			vis[i]=1;
		}
	}
	//全部都是0构造2 1 1 1 1 ...
	if(q.size()==0){
		cout<<2<<' ';
		rep(i,1,n-1){
			cout<<1<<' ';
		}
	}
	//否则找到每个0最近的相同的非零的数,把它变为那个数
	while(q.size()){
		auto t=q.front();
		q.pop();
		if(t>1&&a[t-1]==0){
			a[t-1]=a[t];
			q.push(t-1);
		}
		if(t<n&&a[t+1]==0){
			a[t+1]=a[t];
			q.push(t+1);
		}
	}
	int ans=0;
	rep(i,2,n){
		ans+=abs(a[i]-a[i-1]);
	}

	if(ans>1){
		cout<<-1<<endl;
		return;
	}else if(ans==0){
		//看第一个数和最后一个数最开始是否为0
		if(vis[1]&&vis[n]){
			cout<<-1<<endl;
//			cout<<"AAAAAAA"<<endl;
			return;
		}
		if(!vis[1]){
			a[1]++;
		}else{
			a[n]++;
		}
		rep(i,1,n){
			cout<<a[i]<<' ';
		}
	}else{
		rep(i,1,n){
			cout<<a[i]<<' ';
		}
	}
}

signed main() {
	ios::sync_with_stdio(false);
	cin.tie(0);
	cout.tie(0);
	freopen("1.in", "r", stdin);
	int _;
//	cin>>_;
//	while(_--)
	solve();
	return 0;
}

E

bfs直接去染色然后判断即可。


#include <bits/stdc++.h>
#define int long long
#define rep(i,a,b) for(int i = (a); i <= (b); ++i)
#define fep(i,a,b) for(int i = (a); i >= (b); --i)
#define pii pair<int, int>
#define pdd pair<double,double>
#define ll long long
#define db double
#define endl '\n'
#define x first
#define y second
#define pb push_back
#define vi vector<int>

using namespace std;

void solve() {
	int n;
	cin>>n;
	string s;
	cin>>s;
	vector<vi>g(n+1);
	rep(i,1,n-1){
		int u,v;
		cin>>u>>v;
		u--;
		v--;
		g[u].pb(v);
		g[v].pb(u);
	}
	int cnt=0;
	rep(i,0,n-1){
		if(s[i]=='?'){
			cnt++;
		}
	}
	auto topsort=[&](){
		queue<int>q;
		rep(i,0,n-1){
			if(s[i]!='?'){
				q.push(i);	
			}
		}	
		while(q.size()){
			auto u=q.front();
			q.pop();
			for(auto v:g[u]){
				if(s[v]=='?'){
					if(s[u]=='d'){
						s[v]='p';
					}else{
						s[v]='d';
					}
					q.push(v);
				}
				
			}
		}
	};
	auto check=[&](){
		rep(i,0,n-1){
			for(auto v:g[i]){
				if(s[i]==s[v]){
					return false;
				}
			}
		}
		return true;
	};
	if(cnt==n){
		s[0]='p';
	}
//	cout<<cnt<<endl;
//	exit(0);
	topsort();
	if(check()){
		cout<<s<<endl;
	}else{
		cout<<-1<<endl;
	}
}

signed main() {
	ios::sync_with_stdio(false);
	cin.tie(0);
	cout.tie(0);
//	freopen("1.in", "r", stdin);
	int _;
//	cin>>_;
//	while(_--)
	solve();
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值