Codeforces Round 959 sponsored by NEAR (Div. 1 + Div. 2) (个人题解)(未完成)

前言:

  这是本人参加的第一场cf比赛吧,之前对Codeforces这个平台早有耳闻,也一直有想试一试的想法,但由于这种比赛的阴间时间我一直没有啥机会(试问晚十一点断电断网的学校怎么打这比赛),不过方法总比困难多,想打总是有办法打的,以后我也打算长期打一打这个比赛,希望借此锻炼自己的能力吧!

正文:

比赛链接:Dashboard - Codeforces Round 959 sponsored by NEAR (Div. 1 + Div. 2) - Codeforces

A. Diverse Game:

#include<bits/stdc++.h>
using namespace std;
const int N=1000;
int a[N][N],b[N][N];
int main(){
	int t;
	cin>>t;
	while(t--){
		int n,m;
		scanf("%d%d",&n,&m);
		for(int i=1;i<=n;i++){
			for(int j=1;j<=m;j++){
				scanf("%d",&a[i][j]);
				if(i+1>n)b[1][j]=a[i][j];
				else b[i+1][j]=a[i][j];
			}
		}
		if(n==1&&m==1){
			cout<<-1<<endl;
			continue;
		}
		for(int i=1;i<=n;i++){
			for(int j=2;j<=m+1;j++){
				if(j!=m+1)printf("%d ",b[i][j]);
				else printf("%d ",b[i][1]);
			}
			printf("\n");
		}
	}
	return 0;
}

题目大意就是创建一个矩阵与原矩阵每一位都不同,其中原矩阵中每一位也都不同。这题只有在矩阵大小为1x1时才不成立,其他情况我们将与矩阵每一位的xy都往前或往后移动一位即可,第一位就将他放最后一位就可得出答案。

B. Fun Game:

#include<bits/stdc++.h>
using namespace std;
const int N=2e5+5;
int p0[N],p1[N];
int main(){
	int q;
	cin>>q;
	while(q--){
		int n;
		cin>>n;
		string a,b;
		cin>>a>>b;
		for(int i=1;i<=n;i++){
			if(a[i-1]=='1')p1[i]=p1[i-1]+1;
			else p1[i]=p1[i-1];
		}
		bool flag=true;
		for(int i=n;i>=1;i--){
			if(a[i-1]!=b[i-1]){
				if(a[i-1]=='0'){
					if(p1[i])continue;
					else{
						flag=false;
						break;
					}
				}
				else{
					if(p1[i])continue;
					else{
						flag=false;
						break;
					}
				}
			}
			else continue;
		}
		if(flag)cout<<"YES"<<endl;
		else cout<<"NO"<<endl;
	}
	return 0;
}

题目大意给两个 01 序列 𝑎 和 𝑏,可以进行无限次操作使 𝑎𝑙 到 𝑎𝑟 同时异或 𝑎1 到 𝑎𝑟−𝑙+1。问将 𝑎 通过操作转换为 𝑏 的可行性。我们易知0^1=1,1^1=0,所以只要前面存在1,我们就可以将不同的那一位转化为可行的,直接记录前面有多少1在从后往前遍历即可。

C. Hungry Games:

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
ll a[200005],dp[200005];
int main(){
	int t;
	cin>>t;
	while(t--){
		memset(dp,0,sizeof(dp));
		int n,x;
		ll ans=0;
		scanf("%d%d",&n,&x);
		for(int i=1;i<=n;i++){
			scanf("%lld",&a[i]);
		}
		int res=0,r=1;
		for(int i=1;i<=n;i++){
			res-=a[i-1];
			while(r<=n&&res<=x){
				res+=a[r];r++;
			}
			if(res<=x)continue;
			dp[r]+=dp[i]+1;
		}
		for(int i=2;i<=n+1;i++){
			ans-=dp[i];
		}
		ans+=(ll)n*(n+1)/2;
		printf("%lld\n",ans);
	}
	return 0;
}

dp和双指针的混合题,题目大意为每次可以选择一个区间依次吃蘑菇,初始毒性为 0,吃掉第 𝑖 个蘑菇会使得毒性增加 𝑎𝑖。每次吃掉一个蘑菇后,若受毒性超过x,则将毒性归零。问有多少个区间使得依次吃完蘑菇后的毒性不为 0。我们可以反向考虑,答案要求的区间即为总区间减去毒性为0的区间,总区间为(n+1)*n/2个,而毒性为0的区间我们则需要通过双指针来跑一遍,但双指针得到的情况只是毒性只清零一次的情况,但我们通过dp可以知道总情况,dp[i]表示当r=i时区间毒性为0的情况可以在我们双指针找区间时计算,公式为dp[r]+=dp[i]。最后汇众答案得出正解。

D. Funny Game(待补)

E. Wooden Game(待补)

这两题好像是图论相关,图论的知识我现在还了解不深,等之后再补吧。

F. Stardew Valley(待补)

G. Minecraft(待补)

H. Fortnite(待补)

后面这些题更是不知道我什么时候能补。

后记:

  以后正式开始坚持打cf(太难的就暂时不参加了)了,希望不要放弃吧。

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值