2021牛客寒假算法基础集训营3,签到题DGHIJ

D. Happy New Year!模拟

在这里插入图片描述

#include<bits/stdc++.h>
using namespace std;
int main(){
	ios::sync_with_stdio(false);
	int n;  cin>>n;
	int nn = n, ss = 0;
	while(nn>0){ss+=nn%10; nn/=10;}
	for(int i = n+1; i <= 9999; i++){
		int t = i, sum = 0;
		while(t>0){
			sum += t%10;  t/=10;
		}
		if(sum==ss){
			cout<<i<<"\n";
			return 0;
		}
	}
	return 0;
}

G.糖果 并查集

在这里插入图片描述

//如果这两个人是朋友,必须买相同的糖果数
#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
const int maxn = 1e6+10;
LL n, m, a[maxn];
LL b[maxn], c[maxn];

int fa[maxn+10];
void init(int n){for(int i = 0; i <= n; i++)fa[i]=i;}
int find(int x){return x==fa[x]?x:fa[x]=find(fa[x]);}
void merge(int x, int y){x=find(x);y=find(y);if(x!=y)fa[x]=y;}
int count(int n){int cnt=0; for(int i = 1; i <= n; i++)if(fa[i]==i)cnt++;return cnt;}

int main(){
	ios::sync_with_stdio(false);
	cin>>n>>m;
	for(int i = 1; i <= n; i++)cin>>a[i];
	init(n);
	for(int i = 1; i <= m; i++){
		int x, y;  cin>>x>>y;
		merge(x,y);
	}
	LL sum = 0;
	for(int i = 1; i <= n; i++){
		int x = find(i);//not fa[i]
		c[x]++;
		b[x] = max(b[x],a[i]);
	}
	for(int i = 1; i <= n; i++){
		sum += b[i]*c[i];
	}
	cout<<sum<<"\n";
	return 0;
}

H. 数字串 构造

在这里插入图片描述

//题意:定义转换为将一个字符串的每个字符s[i]-'a'+1形成的数字拼接所形成的新串。给出一个str,求构造一个不同的str但转换结果相同。
//思路:先转换str,然后考虑数字能否拆分和合并,比如15拆成1,5,或者1,5合成15。注意10和20不能拆或合
#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
const int maxn = 1e6+10;

string s, ans;
int check1(){//拆分
	ans = "";
	for(int i = 0; i < s.size(); i++){
		int num = s[i]-'a'+1;
		if(num>10 && num!=20){
			ans += num/10+'a'-1;
			ans += num%10+'a'-1;
		}else {
			ans += s[i];
		}
	}
	return ans.size()!=s.size();
}
int check2(){//合并
	ans = "";
	for(int i = 0; i < s.size(); i++){
		int num = s[i]-'a'+1, num2 = s[i+1]-'a'+1;
		if((num==1||num==2) && (num2>=1&&num2<=6)){
			ans += num*10+num2+'a'-1;
			i++;
		}else{
			ans += s[i];
		}
	}
	return ans.size()!=s.size();
}

int main(){
	cin>>s;
	if(check1()){
		cout<<ans<<"\n";
		return 0;
	}
	if(check2()){
		cout<<ans<<"\n";
		return 0;
	}
	cout<<"-1";
	return 0;
}

I. 序列的美观度 DP或贪心

在这里插入图片描述

//f[i]表示以第i个数字结尾的子序列的最大美观度
//转移:f[i] = max{f[j]+1}(a[i]==a[j]) 或 max{f[j]}(a[i]!=a[j])
//pos[i]维护前i个里面最后一个等于a[i]的位置,mx维护不等于a[i]的dp值中的最大值
#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
const int maxn = 1e6+10;
int a[maxn], pos[maxn], f[maxn];
int main(){
	int n;  cin>>n;
	for(int i = 1; i <= n; i++)cin>>a[i];
	int mx = 0;
	memset(pos,-1,sizeof(pos));
	for(int i = 1; i <= n; i++){
		if(pos[a[i]]==-1)f[i] = mx;
		else f[i] = max(mx,f[pos[a[i]]]+1);
		pos[a[i]] = i;
		mx = max(mx,f[i]);
	}
	cout<<mx<<"\n";
	return 0;
}

J. 加法和乘法 博弈论

在这里插入图片描述

/*题意:
桌面上n张牌,每轮玩家拿出两张,做加法或乘法后放回,牛牛先手。最后奇数则牛牛胜,求谁能胜。
思路:
如果最后一次操作是牛妹进行,则牛妹必胜。(奇数+奇数=偶数,偶数乘以任何数都等于偶数)
否则如果初始状态有至多一个偶数,牛牛总有办法把局面变成全部都是奇数然后交给牛妹,牛妹至多产生一个偶数,因此给牛牛时局面不变。在最终时由于最多只有一个偶数,所以牛牛必胜。
反之,如果初始状态有至少两个偶数,无论牛牛怎么操作,牛妹还给牛牛的时候一定还有至少两个偶数,所以牛牛最后面对的局面就是两个偶数,牛妹必胜。
*/
#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
const int maxn = 1e6+10;
int main(){
	int n;  cin>>n;
	if(n==1){
		int x;  cin>>x;
		printf("%s", x%2==1?"NiuNiu":"NiuMei");
		return 0;
	}
	int a=0,b=0;
	for(int i = 1; i <= n; i++){
		int x;  cin>>x;
		if(x%2==1)a++;
		else b++;
	}
	printf("%s", (n%2==1||b>1)?"NiuMei":"NiuNiu");
	return 0;
}

已标记关键词 清除标记
相关推荐
©️2020 CSDN 皮肤主题: 技术工厂 设计师:CSDN官方博客 返回首页