cf gym 102785

Posted yeah17981

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了cf gym 102785相关的知识,希望对你有一定的参考价值。

日常训练系列~

本人在成功的过了三题后完美摸鱼

然后

然后终榜上就真的只过了三题

哭唧唧

传送门

a.A lazy controller:签到题,给n组数据,每组数据有a b两个数构成,如果b不是a的倍数,输出“DEFECT
“除此之外,c=b/a,如果n组数据的c全部相同,输出”QUALITY“,否则输出”DEFECT“

真签到好伐,我都不想放代码上来了

b.Gremlins attack:给一个n*n的表格,有m只鬼,k盏明灯,告诉你鬼的位置和这k盏灯的位置,鬼只能在有光的地方走,最开始的时候除了鬼的位置其他都是暗的,这k盏灯依次变亮,问亮到第几盏的时候鬼能逃跑(到达表格边界)

很明显是dfs,每次更新新点,并且在新点的基础上搜索能不能同时到达边界和鬼所在的位置,可以的话输出并跳出

对,就是找个跳出,我他妈找了一天的bug,最后发现是一直输出没有截止

虽然但是找个bfs也不是我写的

#include<iostream>
using namespace std;
 
int n,m,k,x,y,step=0;
int dark[1000][1000],connect[1000][1000];
int flag=0;
void make(int x,int y)
{
	if(x>0)
	{
		if(connect[x-1][y]==1) connect[x][y]=1;
	}
	if(x<n-1)
	{
		if(connect[x+1][y]==1) connect[x][y]=1;
	}
	if(y>0)
	{
		if(connect[x][y-1]==1) connect[x][y]=1;
	}
	if(y<n-1)
	{
		if(connect[x][y+1]==1) connect[x][y]=1;
	}
}
 
void dfs(int x,int y)
{
	if(x>0)
	{
		if(dark[x-1][y]==1 && connect[x-1][y]==0)
		{
			connect[x-1][y]=1;
			if((x-1==0 || x-1==n-1 )||(y==0 || y==n-1))
			{
				if(flag!=1) 
				cout<<step<<endl;
				flag=1;
				return;
			} 
			dfs(x-1,y);	
		}
	}
	if(x<n-1)
	{
		if(dark[x+1][y]==1 && connect[x+1][y]==0)
		{
			connect[x+1][y]=1;
			if((x+1==0 || x+1==n-1 )||(y==0 || y==n-1))
			{
				if(flag!=1) 
				cout<<step<<endl;
				flag=1;
				return;
			} 
			dfs(x+1,y);
		}		
	}
	if(y>0)
	{
		if(dark[x][y-1]==1 && connect[x][y-1]==0)
		{
			connect[x][y-1]=1;
			if((x==0 || x==n-1 )||(y-1==0 || y-1==n-1))
			{
				if(flag!=1) 
				cout<<step<<endl;
				flag=1;
				return;
			}
			dfs(x,y-1);	 	
		}
	}
	if(y<n-1)
	{
		if(dark[x][y+1]==1 && connect[x][y+1]==0)
		{
			connect[x][y+1]=1;
			if((x==0 || x==n-1 )||(y+1==0 || y+1==n-1))
			{
				if(flag!=1) 
				cout<<step<<endl;
				flag=1;
				return;
			} 
			dfs(x,y+1);		
		}
	}
}
 
int main()
{
//freopen("in.in","r",stdin);//读入数据生成器造出来的数据
//freopen("baoli.txt","w",stdout);
	cin>>n>>m>>k;
	for(int i=1;i<=n;i++)
		for(int j=1;j<=n;j++)
		{
			dark[i][j]=0;
			connect[i][j]=0;
		}	
	for(int i=1;i<=m;i++)
	{
		cin>>x>>y;
		dark[x][y]=1;connect[x][y]=1;
		if((x==0 || x==n-1 )||(y==0 || y==n-1))
		{
			cout<<step<<endl;
			return 0;
		}
	}
	for(int i=1;i<=k;i++)
	{
		cin>>x>>y;step++;
		dark[x][y]=1; make(x,y);
		if(connect[x][y]==1)
		{
			if((x==0 || x==n-1 )||(y==0 || y==n-1))
			{
				cout<<step<<endl;
				return 0;
			}
			dfs(x,y);
			if(flag==1) return 0;
		}	
	}
	cout<<"0\\n";
		return 0;
} 

也可以用并查集将能到达边界的灯和鬼分别放到两个点里(构造),当两个点在一个集中说明此时鬼可以到达边界,输出!

比赛的时候两种方法都写了,并查集爆了,dfs没有标记,喜提wa11

D:dp,在学

E.Hanoi Tower:汉诺塔变形,给一个01串a,a0是顶端的环的状态,an是底端的环的状态,求在汉诺塔的规则下将第一个柱子从1……1到a的最小步数的二进制表达

本题需要在脑海中模拟汉诺塔的步骤,建议配合视频使用 汉诺塔

考虑到一个高度为n的汉诺塔从1到3需要的步数为f[n]=2*f[n-1]+1,用二进制表达就是1……1

又考虑到我们并不需要关心23号柱子上面有几个,所以高度为n的汉诺塔移出只需要f[n-1]+1,即10……0

建一个数组的dp,dp[k]表示用二进制表示步数下第k位的数值

然后从下到上模拟,并记录第i位上面没有处理的部分是在1(flag=0)还是在23(flag=1),将底端的连续的1忽略掉,反正他们也不动。

如果i是0,flag==0,往上记录此时有f个连续的0

        如果f==1,将i-1及一上的移到2,i移到3(等同于将高度为i的汉诺塔移出)此时dp[i]++

        如果f==0,将i-1及一上的移到2,i移到3写着写着发现好像不用分类,我是傻逼

将高度为i的汉诺塔移出,此时dp[i]++,且上面部分在2的位置

flag==1不用处理,上部分也还在2的位置

如果i为1,此时一定在2的位置,将高度为i的汉诺塔移到1,即为dp[i+1]++且dp[1]--

但是(划重点)让我们来模拟这几个连续1里最后一个1的操作,当它归位时,此时它上面的环应该是摆好了的,因为我们并不需要他们也跟着回去,所以这里要减去 ,即dp[i-t+1]--且dp[1]--,flag=1

想不明白就看视频

最后处理dp,>=2就进位,<0就借位,结束

#include<bits/stdc++.h>
using namespace std;
char z[200];
int dp[200];
int main()
{
	int n,f=0,t=0,flag=0;
	cin>>n;
	cin>>z;
	int l=n;
	for(int i=n-1;i>=0;i--)
	{
		if(flag==0&&z[i]=='1')
		{
			l--;
			z[i]-='1';
		}
		if(z[i]=='0') 
		{
			flag=1;
			break;
		}
	}//这部分没错 
	bool flag1=0,flag2=0;
	int len=l;
	for(int i=l-1;i>=0;)
	{
		while(z[i]=='0'&&i>=0)
		{
			f++;
			i--;
		}
		if(flag1==0)
		{
			if(f==1)	dp[l-f+1]++;
			else 	dp[l]++;
			flag2=1;
		}//只移0,不动1 
		else
		{
				flag2=1; 
		}
		l=l-f;
		f=0;
		while(z[i]=='1'&&i>=0)
		{
			t++; 
			i--;
		}
		
			dp[l+1]++;
			dp[l-t+1]--;
			flag1=1;
			//dp[1]-=2;
			l-=t;t=0;
		if(l==0)break;
	}
	flag=1;
	for(int i=1;;i++)
	{
		if(dp[i]==0&&i>len)
		{
			break;
		}
		else
		{
			if(dp[i]!=0)
			{
				if(dp[i]>=0)
				{
					dp[i+1]+=dp[i]/2;
				dp[i]=dp[i]%2;
				flag=i;
				}
				else
				{
					if(dp[i]%2==0)
					dp[i+1]+=dp[i]/2;
					else
					dp[i+1]+=dp[i]/2-1;
				dp[i]=-dp[i]%2;
				flag=i;
				}
				
			}
			
		}
	}
	for(int i=flag;i>=1;i--)
	{
		cout<<dp[i];	
	}
	
 } 

H.A self-describing sequence:构造,1236无解,45题目给了,其他以0-9为例

0123456789

6210001000

0:n-3

1:2

2:1

n-3:1

结束

#include<bits/stdc++.h>
using namespace std;
const int maxn=1e6;
string f;
int main(){
	long long n,z,i;
	long long k,flag=0;
	cin>>n>>k;
	if(n==1||n==2||n==3||n==6) flag=1;
	else if(n==4)
	{
		f="1210";
	}
	else if(n==5)
	{
		f="21200";
	}
	if(flag==0) cout<<k<<"\\n";
	else
	{
		cout<<"0\\n";
	}
	for( i=1;i<=k;i++)
	{
		cin>>z;
		if(flag==0) 
		{
			if(n==4||n==5)
			cout<<f[z]<<" "; 
			else if(z==0)
			{
				cout<<n-4<<" ";
			}
			else if(z==1)
			{
				cout<<2<<" ";
			}
			else if(z==2)
			{
				cout<<1<<" ";
			}else if(z==n-4)
			{
				cout<<1<<" ";
			}
			else
			{
				cout<<"0 ";
			}
		}
	}
}

j:给两个字符串,串z带*和+且不存在连续的+*,a*代表0-无数个a,a+代表1-无数个a,问zp能否匹配

首先将a+转换成aa*

dp[i][j]表示第i位和j位能否匹配

不想写了,自己看,毁灭吧

#include<bits/stdc++.h>
using namespace std;
const int maxn=2e3+10;
char a[maxn],b[maxn],c[maxn],d[maxn];
int dp[maxn][maxn];
int main(){
	cin>>a>>b;
	int len1=strlen(a);
	int len2=strlen(b);
	int k=1;
	for(int i=0;i<len1;i++)
	{
		c[i+k]=a[i];
		if(a[i]=='+')
		{
			c[i+k]=c[i+k-1];
			k++;
			c[i+k]='*';
		 } 
	 } //把*换+
	 len1+=k;
	 len1--;
	 for(int i=0;i<len2;i++)
	{
		d[i+1]=b[i];
	 } 
	 //cout<<len1<<" "<<len2<<"\\n";
	 dp[0][0]=1;
	 for(int i=1;i<=len1;i++)
	 {
	 	if(c[i]=='*')
	 	{
	 		dp[i][0]=dp[i-2][0];
		 }
	  } //可能存在z的前面没有匹配的
	 for(int i=1;i<=len1;i++)
	 {
	 	for(int j=1;j<=len2;j++)
	 	{
	 		if(c[i]==d[j])
	 		{
	 			dp[i][j]=dp[i-1][j-1];
	 			//cout<<i<<"x"<<j<<" ";
				//cout<<c[i]<<" "<<d[j]<<" "<<dp[i][j]<<"\\n"; 
			 }//简单易懂
			 else
			 {
			 	if(c[i]=='*')
			 	{
			 		if(dp[i-2][j]==1||dp[i-1][j]==1)//a*转a或空

			 		{
			 			dp[i][j]=1;
			 			//cout<<i<<"b"<<j<<" ";
						//cout<<c[i]<<" "<<d[j]<<" "<<dp[i][j]<<"\\n"; 
					 }
					 else if(c[i-1]==d[j]&&(dp[i-1][j-1]==1||dp[i][j-1]==1))
					 {
					 	dp[i][j]=1;
					 	//cout<<i<<"a"<<j<<" ";
						//cout<<c[i-1]<<" "<<d[j]<<" "<<dp[i][j]<<"\\n"; 
					 }
				 }
			 }
		 }
	 }
	 //cout<<len1<<" "<<len2<<" ";
	 if(dp[len1][len2]==1){
	 	cout<<"Yes\\n";
	 }
	 else
	 {
	 	cout<<"No\\n";
	 }
}

over

以上是关于cf gym 102785的主要内容,如果未能解决你的问题,请参考以下文章

CF Gym Dice Game BFS 暴搜

cf gym 100960 G. Youngling Tournament set+树状数组

cf gym 101124

CF Gym-101911A Coffee Break

CF Gym 102059E Electronic Circuit (set存图删点)

CF gym102759IQuery On A Tree 17