题目描述
在奶牛回家休息和娱乐之前,Farmer John 希望它们通过玩游戏获得一些智力上的刺激。游戏板由 n 个相同的孔组成,这些孔最初都是空的。一头母牛要么用石头盖住一个洞,要么揭开一个先前被盖住的洞。游戏状态的定义是哪些洞被石头覆盖,哪些洞没有覆盖。游戏的目标是让奶牛准确地到达每个可能的游戏状态一次,然后返回到所有洞都没有覆盖的状态。以下是他们其中一次游戏的示例(空的洞用 O
表示,用石头盖住的洞用 X
表示):
时间 | 洞 1 | 洞 2 | 洞 3 | 描述 |
---|---|---|---|---|
00 | O | O | O | 一开始所有的洞都是空的 |
11 | O | O | X | 盖上洞 3 |
22 | X | O | X | 盖上洞 1 |
33 | X | O | O | 打开洞 3 |
44 | X | X | O | 盖上洞 2 |
55 | O | X | O | 打开洞 1 |
66 | O | X | X | 盖上洞 3 |
77 | X | X | X | 盖上洞 1 |
现在牛被卡住玩不下去了!他们必须打开一个洞,不管他们打开哪个洞,他们都会到达一个他们已经到达的状态。例如,如果他们从第二个洞中取出岩石,他们将到达他们在时间 22 已经访问过的状态(X O X
)。
下面是一个 3 个孔的有效解决方案:
时间 | 洞 1 | 洞 2 | 洞 3 | 描述 |
---|---|---|---|---|
00 | O | O | O | 一开始所有的洞都是空的 |
11 | O | X | O | 盖上洞 2 |
22 | O | X | X | 盖上洞 3 |
33 | O | O | X | 打开洞 2 |
44 | X | O | X | 盖上洞 1 |
55 | X | X | X | 盖上洞 2 |
66 | X | X | O | 打开洞 3 |
77 | X | O | O | 打开洞 2 |
88 | O | O | O | 打开洞 1,恢复到原来的状态 |
现在,奶牛们厌倦了这个游戏,它们想找你帮忙。
给定 n,求游戏的有效解决方案序列。如果有多个解决方案,则返回任意一个。
输入格式
仅一行,一个整数 n。
输出格式
共 2n+1 行,每行一个长度为 n 的字符串,其中只包含字符 O
和 X
,该行中的第 i 个字符表示第 i 个孔在此状态下是被覆盖还是未覆盖,第一行和最后一行必须全部都是 O
。
输入输出样例
输入
3
输出
OOO OXO OXX OOX XOX XXX XXO XOO OOO
说明/提示
样例 1 说明
见题目描述。
数据规模与约定
对于 100% 的数据,有 1≤n≤15。
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int M=4e4+10;
const int N=1e6+10;
int n;
bool flag[N],a[N]={false},b[N][20];
int check()
{int ans=0;for(int i=1;i<=n;i++){ans=ans*2+flag[i];}return ans;
}
void dfs(int step)
{if(step==(1<<n)){for(int i=1;i<=(1<<n);i++){for(int j=1;j<=n;j++){if(b[i][j])cout<<"X";elsecout<<"O";}cout<<endl;}exit(0);}for(int i=1;i<=n;i++)//尝试每一个点作为改变的起点{flag[i]=!flag[i];if(a[check()])//如果已经出现过,则代表此点被改变后的所有情况都出现过,所以直接跳过{flag[i]=!flag[i];continue;}a[check()]=true;for(int j=1;j<=n;j++) b[step][j]=flag[j];dfs(step+1);flag[i]=!flag[i];//尝试下一个点,将此点变为原样 }
}
void solve()
{cin>>n;for(int i=1;i<=n;i++) cout<<"O";//先输出cout<<endl;a[check()]=true;//将第一种情况直接设置为已经走过dfs(1);return ;
}
int main()
{ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);ll t=1;
// cin>>t;while(t--){ solve();}return 0;
}