USACO历年白银组真题解析 | 2010年3月
2026/6/6 1:46:31 网站建设 项目流程

​欢迎大家订阅我的专栏:算法题解:C++与Python实现!
本专栏旨在帮助大家从基础到进阶 ,逐步提升编程能力,助力信息学竞赛备战!

专栏特色
1.经典算法练习:根据信息学竞赛大纲,精心挑选经典算法题目,提供清晰的代码实现与详细指导,帮助您夯实算法基础。
2.系统化学习路径:按照算法类别和难度分级,从基础到进阶,循序渐进,帮助您全面提升编程能力与算法思维。

适合人群:

  • 准备参加蓝桥杯、GESP、CSP-J、CSP-S等信息学竞赛的学生
  • 希望系统学习C++/Python编程的初学者
  • 想要提升算法与编程能力的编程爱好者

附上汇总贴:USACO历年白银组真题解析 | 汇总-CSDN博客


P6183 The Rock Game

【题目来源】

洛谷:P6183 [USACO10MAR] The Rock Game S - 洛谷

【题目描述】

在奶牛回家休息和娱乐之前,Farmer John 希望它们通过玩游戏获得一些智力上的刺激。

游戏板由n nn个相同的洞组成,这些洞最初都是空的。一头母牛要么用石头盖住一个空的洞,要么揭开一个先前被盖住的洞。游戏状态的定义是所有洞是否被石头覆盖的情况。

游戏的目标是让奶牛到达每个可能的游戏状态一次,最后回到初始状态。

以下是他们其中一次游戏的示例(空的洞用O表示,用石头盖住的洞用X表示):

时刻洞 1洞 2洞 3描述
0 00OOO一开始所有的洞都是空的
1 11OOX盖上洞 3
2 22XOX盖上洞 1
3 33XOO打开洞 3
4 44XXO盖上洞 2
5 55OXO打开洞 1
6 66OXX盖上洞 3
7 77XXX盖上洞 1

现在牛被卡住玩不下去了!他们必须打开一个洞,然而不管他们打开哪个洞,他们都会到达一个他们已经到达过的状态。例如,如果他们从第二个洞中取出岩石,他们将到达他们在时刻2 22已经访问过的状态(X O X)。

下面是一个 3 个孔的有效解决方案:

时间洞 1洞 2洞 3描述
0 00OOO一开始所有的洞都是空的
1 11OXO盖上洞 2
2 22OXX盖上洞 3
3 33OOX打开洞 2
4 44XOX盖上洞 1
5 55XXX盖上洞 2
6 66XXO打开洞 3
7 77XOO打开洞 2
8 88OOO打开洞 1,恢复到原来的状态

现在,奶牛们厌倦了这个游戏,它们想找你帮忙。

给定n nn,求游戏的有效解决方案序列。如果有多个解决方案,则输出任意一个

【输入】

仅一行,一个整数n nn

【输出】

2 n + 1 2^n+12n+1行,每行一个长度为n nn的字符串,其中只包含字符OX,该行中的第i ii个字符表示第i ii个孔在此状态下是被覆盖还是未覆盖,第一行和最后一行必须全部都是O

【输入样例】

3

【输出样例】

OOO OXO OXX OOX XOX XXX XXO XOO OOO

【解题思路】

【算法标签】

《洛谷 P6183 The Rock Game》 #深度优先搜索,DFS# #USACO# #Special judge# #2010#

【代码详解】

#include<bits/stdc++.h>usingnamespacestd;intn,a[20],vis[65536];intans[65536][20];intcalc()// 将二进制数转为十进制数{intans=0;for(inti=1;i<=n;i++){ans=ans*2+a[i];}returnans;}voiddfs(intstep){if(step==pow(2,n)){// 当step等于2^n,就进行输出for(inti=1;i<=pow(2,n);i++){// 遍历ans二维数组for(intj=1;j<=n;j++){if(ans[i][j]==1)cout<<"X";// 如果当前位置为1就输出Xelsecout<<"O";// 否则就输出O}cout<<endl;// 每输出完后就换一行}exit(0);// 只要完成一组输出,就结束程序}for(inti=1;i<=n;i++){// 遍历1到n个位置a[i]=!a[i];// 对当前位置进行取反操作if(vis[calc()]==1){// 如果当前二进制数访问过a[i]=!a[i];// 还原现场continue;// 继续下一次循环}vis[calc()]=1;// 如果这个数之前没有出现过,则标记为1for(intj=1;j<=n;j++){// 使用二维数组记录下当前二进制数ans[step][j]=a[j];}dfs(step+1);// 进行下一次搜索vis[calc()]=0;// 还原现场a[i]=!a[i];}}intmain(){cin>>n;// 输入nfor(inti=1;i<=n;i++){// 先输出第一行全Ocout<<'O';}cout<<endl;vis[0]=1;// 标记全0的二进制数已经访问过dfs(1);// 进行dfs深搜return0;}

【运行结果】

3 OOO XOO XXO OXO OXX XXX XOX OOX OOO

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询