Codeforces Round #550 (Div. 3)【补】

我实在是太鸡了,天天gugugu不说,题也不会写,只能开始漫长的补题生活了。
A. Diverse Strings

#include <algorithm>
#include <iostream>
#include <cstring>
#include <cstdio>
#include <string>
#include <vector>
#include <queue>
#include <stack>
#include <cmath>
#include <map>
#include <set>
#define mm(i,v) memset(i,v,sizeof i);
using namespace std;
typedef long long ll;
char str[1000000];
ll T,n;
int main()
{
    ll i,j;
    cin>>T;
    while(T--)
    {
			cin>>str+1;
			n=strlen(str+1);
			sort(str+1,str+n+1);
			for(i=1;i<n;i++) if(str[i]!=str[i+1]-1) break;
			if(i<n) puts("No");
			else puts("Yes");
    }
}

B. Parity Alternated Deletions
大概就是删一次奇数,删一次偶数,求出最后剩下的数加起来的最小值。
直接模拟

#include <algorithm>
#include <iostream>
#include <cstring>
#include <cstdio>
#include <string>
#include <vector>
#include <queue>
#include <stack>
#include <cmath>
#include <map>
#include <set>
#define mm(i,v) memset(i,v,sizeof i);
using namespace std;
typedef long long ll;
const int maxn=2000+10;
ll a[maxn],n;
vector<ll> odd,even;
ll ans;
int main(){
	ios::sync_with_stdio(false);
	cin.tie(0);
	cin>>n;
	for(int i=1;i<=n;i++){
		cin>>a[i];
		ans+=a[i];
		if(a[i]&1)
			odd.push_back(a[i]);
		else
			even.push_back(a[i]);
	}
	sort(odd.begin(),odd.end());
	sort(even.begin(),even.end());
	int so=odd.size()-1,se=even.size()-1,f=0;
	cout<<so<<se<<endl;
	if(odd.size()>even.size())
		f=1;
	while(1){
		if(f==0){
			if(se<0)
				break;
			ans-=even[se];
			se--;
		}
		if(f==1){
			if(so<0)
				break;
			ans-=odd[so];
			so--;
		}
		f^=1;
	}
	cout<<ans<<"\n";
	return 0;
}

C. Two Shuffled Sequences
给出一组数,先按升序输出一串,再按降序输出一串,保证每串都没重复的,而且一个数只能用一次。

#include <algorithm>
#include <iostream>
#include <cstring>
#include <cstdio>
#include <string>
#include <vector>
#include <queue>
#include <stack>
#include <cmath>
#include <map>
#include <set>
#define mm(i,v) memset(i,v,sizeof i);
using namespace std;
typedef long long ll;
const int maxn=200009;
int a[maxn],num[maxn];
vector<int> inc,decr;
int n;
int main(){
	mm(num,0);
	ios::sync_with_stdio(false);
	cin.tie(0);
	cin>>n;
	for(int i=1;i<=n;i++){
		cin>>a[i];
		num[a[i]]++;
	}
	for(int i=0;i<=200000;i++){//不是很懂为什么这儿写maxn就错,疯狂卡我,交了无数次!
		if(num[i] >= 3) {
			cout<<"NO"<<endl;
			return 0;
		}
	}
	for(int i=0;i<=200000;i++){
		if(num[i]>=2)
			inc.push_back(i);
	}
	for(int i=200000;i>=0;i--){
		if(num[i]>=1)
			decr.push_back(i);
	}
	cout<<"YES\n";
	cout<<(int)inc.size()<<"\n";
	for(int i=0;i<inc.size();i++)
		cout<<inc[i]<<(i==inc.size()-1? "\n":" ");
	cout<<(int)decr.size()<<"\n";
	for(int i=0;i<decr.size();i++)
		cout<<decr[i]<<(i==decr.size()-1? "\n":" ");
	return 0;
}

D. Equalize Them All
个人感觉这题是很的水。去个绝对值,再观察一下式子,就直接找到思路了。
简言之就是,找到出现最多的数,比它位置小而且小于他的数执行操作1,大于它的数执行操作2。比它位置大的数大于他就操作2,小于就操作1.

#include <algorithm>
#include <iostream>
#include <cstring>
#include <cstdio>
#include <string>
#include <vector>
#include <queue>
#include <stack>
#include <cmath>
#include <map>
#include <set>
#define mm(i,v) memset(i,v,sizeof i);
using namespace std;
typedef long long ll;
const int maxn=200010;
int a[maxn],num[maxn];

int main(){
	ios::sync_with_stdio(false);
	cin.tie(0);
	int n,pos,t;
	cin>>n;
	for(int i=1;i<=n;i++){
		cin>>a[i];
		num[a[i]]++;
	}
	int minn=n;
	for(int i=0;i<200010;i++){
		if(n-num[i]<minn){
			minn=n-num[i];
			pos=i;
		}
	}
	cout<<minn<<"\n";
	queue<int> q;
	for(int i=1;i<=n;i++){
		if(a[i]==pos)
			q.push(i);
	}
	while(!q.empty()){
		t=q.front();
		q.pop();
		if(t>1&&a[t-1]!=a[t]){
			if(a[t-1]<a[t])
				cout<<1<<" "<<t-1<<" "<<t<<"\n";
			else
				cout<<2<<" "<<t-1<<" "<<t<<"\n";
			a[t-1]=a[t];
			q.push(t-1);
		}
		if(t<n&&a[t+1]!=a[t]){
			if(a[t+1]>a[t])
				cout<<2<<" "<<t+1<<" "<<t<<"\n";
			else
				cout<<1<<" "<<t+1<<" "<<t<<"\n";
			a[t+1]=a[t];
			q.push(t+1);
		}
	}
	return 0;
}

E. Median String
大概就是给了两串字符串,按字典序从第一个到第二个,让你输出中间的一个。

#include <algorithm>
#include <iostream>
#include <cstring>
#include <cstdio>
#include <string>
#include <vector>
#include <queue>
#include <stack>
#include <cmath>
#include <map>
#include <set>
#define mm(i,v) memset(i,v,sizeof i);
using namespace std;
typedef long long ll;
const int maxn=200000+10;
int n,a[maxn],b[maxn],c[maxn];
int cc=0;
string s,t;

int main(){
	ios::sync_with_stdio(false);
	cin.tie(0);
	cin>>n>>s>>t;
	for(int i=0;i<n;i++)
		a[i]=(s[i]-'a');
	for(int i=0;i<n;i++)
		b[i]=(t[i]-'a');
	for(int i=0;i<n;i++){
		c[i]=(a[i]+b[i])/2;
		c[i]+=cc;
		int temp=i;
		while(c[temp]>=26){
			c[temp]-=26;
			c[temp-1]+=1;
			temp--;
		}
		if((a[i]+b[i])%2==1)
			cc=13;
		else
			cc=0;
	}
	for(int i=0;i<n;i++)
		cout<<(char)('a'+c[i]);
	cout<<"\n";
	return 0;
}

F. Graph Without Long Directed Paths
题意 给你n个点 m条边 保证联通 问你能否构造一张有向图(不一定联通)使得路径长度不超过2

我们很容易想到从一个点开始染色 和他相连的点染相反颜色 然后再继续递归下去染色

但是要判断一下 这个点染色和下个点染色是否相反 如果那个点已经有颜色和自己是一样的 那么肯定是NO

#include <algorithm>
#include <iostream>
#include <cstring>
#include <cstdio>
#include <string>
#include <vector>
#include <queue>
#include <stack>
#include <cmath>
#include <map>
#include <set>
#define mm(i,v) memset(i,v,sizeof i);
using namespace std;
typedef long long ll;
const int maxn=1<<18;
int u[maxn],v[maxn],col[maxn];
bool f=0;
vector<int> m[maxn];

void dfs(int cur,int dep){
	if(col[cur]>=0){
		if(col[cur]!=dep)
			f=1;
		return ;
	}
	col[cur]=dep;
	for(int i=0;i<m[cur].size();i++){
		dfs(m[cur][i],dep^1);
	}
}

int main(){
	ios::sync_with_stdio(false);
	cin.tie(0);
	mm(col,-1);
	int n,mm;
	cin>>n>>mm;
	for(int i=1;i<=mm;i++){
		cin>>v[i]>>u[i];
		m[v[i]].push_back(u[i]);
		m[u[i]].push_back(v[i]);
	}
	dfs(1,0);
	if(f==1){
		cout<<"NO\n";
		return 0;
	}
	cout<<"YES\n";
	for(int i=1;i<=mm;i++){
		if(col[v[i]]==0)
			cout<<1;
		else
			cout<<0;
	}
	return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值