0
点赞
收藏
分享

微信扫一扫

七便士第十三届ICPC

技术只适用于干活 2022-04-29 阅读 97
c++
时间限制:C/C++ 1秒,其他语言2秒
空间限制:C/C++ 524288K,其他语言1048576K
64bit IO Format: %lld

题目描述

七便士谜题是一个古老的谜题(如下左图),其规则如下:

• 方盘上有八个圆坑,每个圆坑能正好放置一枚便士,每个圆坑与其他另外两个圆坑相连(图中黑线);
• 每次操作分为两部分:(每次操作两部分缺一不可)

  1. 将一枚便士放置于一个尚未放置便士的圆坑中;
  2. 再将该便士沿着黑线移动至另一尚未放置便士的圆坑中;

• 目标为成功放置七枚便士;

为更好理解七便士谜题规则,现将圆坑按顺时针1~8编号,如上右图所示,i (1≤i≤8)圆坑与(i+2)mod  8+1圆坑和(i+4)mod8+1圆坑间分别存在一条边。
布丁曾尝试解这个谜题,但是中途被艾洛叫去玩游戏了,于是留下了一个七便士残局。
现在问题是,在方盘上已经存在一些硬币的情况下,是否能够通过一定的操作达成在方盘上放置七便士的目标。

输入描述:

第一行,一个整数T,表示有T (1≤T≤255)组询问。
对于每组询问,输入一行,包含一个长度为8的01字符串,表示放置状况,第i个字符为 '\textbf{1}' 表示i号圆坑上已经存在一枚便士,为'0'则无,保证'1'的个数≤7。

输出描述:

对于每组询问,输出一行,一个字符串。"Yes"表示能够放置7枚便士,反之输出"No"(不包括引号)。

示例1

输入

2
01101101
00010100

输出

Yes
No

说明

对于第一组询问: 

放置 4 号圆坑后移至 1 号圆坑。 

放置 4 号圆坑后移至 7 号圆坑。 

便成功放置 7 枚便士。

源代码

#include <iostream>
using namespace std;
int a[10];//数组存储 
bool flag;//有解标志 
int ans;//答案个数 
void dfs()
{
	for(int i = 1;i <= 8;i ++ )//从第一到第八个查 
	{
		if(a[i]==0)//如果当前可走 
		{
			if(a[(i+2)%8+1]==0)//且分支可走 
			{
				a[i]=1;//走 
				ans++;//答案加一 
				if(ans==7)//如果答案满足7
				{
					flag=true;//有解 
					return;//回溯 
				}
				dfs();//如果答案不为7,继续搜 
				if(ans==7)return;//回溯期间答案为7,则一直回溯至结束 
				a[i]=0;//若回溯不为七则此路不同回溯寻找其他分支 
				ans--;//回溯恢复 
			}
			if(a[(i+4)%8+1]==0)//且分支可走 
			{
				a[i]=1;//走 
				ans++;//答案加一 
				if(ans==7)//如果答案满足7
				{
					flag=true;//有解
					return;//回溯 
				}
				dfs();//如果答案不为7,继续搜 
				if(ans==7)return;//回溯期间答案为7,则一直回溯至结束 
				a[i]=0;//若回溯不为七则此路不同回溯寻找其他分支 
				ans--;//回溯恢复 
			}
		}
	}
}
int main()
{
	int n;
	cin>>n;
	while(n--)//n个样例 
	{
		a[10]={0};//初始化 
		flag=false;
		ans=0;
		string s;
		cin>>s;
		for(int i = 1;i <= 8;i ++ )//字符串转化为数组1-8的便士放置情况 
		{
			a[i]=s[i-1]-'0';
			if(a[i]==1)ans++;//若为1则答案加一 
		}
		if(ans==7)cout<<"Yes"<<endl;//若刚好七便士则输出正确 
		else 
		{
			dfs();//否则开始深搜 
			if(flag)cout<<"Yes"<<endl;//搜到某一条路径可以走,输出正确 
			else cout<<"No"<<endl;//无路可走输出错误 
		}
	} 
	return 0;
}
举报

相关推荐

0 条评论