zoj 1008 Gnome Tetravex
2015-07-23 22:49
246 查看
题目链接
题意 有一些卡片上下左右均有数字,要求将这些卡片拼成正方形,并且相接部分数字相同:
思路:dfs深搜,但要注意如果直接暴力的话,深搜是一个全排列问题,计算量最大是为25!,这个数字是非常大的,但如果对卡片进行分类,即上下左右均相等的卡片分成一类,这样全排列的计算量将大大减小,
这里我测试了两种思路稍有不同的代码,如下:
经测试第二种稍微快一点,应该是是因为跳出的较快, 总的来说对dfs的返回及恢复初始值问题是比较难理解透彻的,稍不注意就超时或者其他各种问题
此外本体还应注意一些换行及空格问题,oj无情啊。。。
题意 有一些卡片上下左右均有数字,要求将这些卡片拼成正方形,并且相接部分数字相同:
思路:dfs深搜,但要注意如果直接暴力的话,深搜是一个全排列问题,计算量最大是为25!,这个数字是非常大的,但如果对卡片进行分类,即上下左右均相等的卡片分成一类,这样全排列的计算量将大大减小,
这里我测试了两种思路稍有不同的代码,如下:
经测试第二种稍微快一点,应该是是因为跳出的较快, 总的来说对dfs的返回及恢复初始值问题是比较难理解透彻的,稍不注意就超时或者其他各种问题
此外本体还应注意一些换行及空格问题,oj无情啊。。。
#include<iostream> #include<stdio.h> using namespace std; int n,q; int isqure[25][4];//储存卡片的种类 int icount[25];//储存每种卡片的数量 int itable[25];//存储各位置放置的卡片种类 int dfs(int num) { int i; if(num==n*n)//最后一个卡片已经放置完成,返回 return 1; for(i=0;i<q;i++)//检查每一个卡片能否放置 { if(icount[i]==0)//该种类卡片无剩余,搜索下一个 continue; if(num%n!=0)//不是最左边一行,检查与左边连接处数字是否相同 if(isqure[itable[num-1]][1]!=isqure[i][3]) continue; if(num>=n)不是最上面一行,检查与上面连接处数字是否相同 if(isqure[itable[num-n]][2]!=isqure[i][0]) continue; itable[num]=i;//标记该位置放置的卡片种类 icount[i]--;//卡片数量减1 if(dfs(num+1)==1) return 1; //注意理解这里的返回与卡片数量的恢复, icount[i]++; } return 0; } int main() { //freopen("in.txt","r",stdin); int ans=1; while(scanf("%d",&n)!=EOF&&n) { q=0;//卡片的种类 int top,right,bottm,left; for(int i=0;i<n*n;i++) { scanf("%d%d%d%d",&top,&right,&bottm,&left); int j=0; for(j=0;j<q;j++)//检查输入的卡片是否已将存过,若存过,该种类数量加1 { if(isqure[j][0]==top && isqure[j][1]==right && isqure[j][2]==bottm && isqure[j][3]==left) { icount[j]++; break; } } if(j==q)//如果没存过该种卡片,建立新的卡片种类,并使其初始值为1,同时卡片种类q加1 { isqure[j][0]=top; isqure[j][1]=right; isqure[j][2]=bottm; isqure[j][3]=left; q++; icount[j]=1; } } int flag=dfs(0); if(ans-1) printf("\n"); printf("Game %d: ",ans++); if(flag) printf("Possible\n"); else printf("Impossible\n"); } }
#include<iostream> #include<stdio.h> using namespace std; int n,q,flag; int isqure[25][4]; int icount[25]; int itable[25]; void dfs(int num) { int i; if(flag)return;//这里如果没有一个检查过程,本解法将会超时 if(num==n*n) { flag=1; return ; } for(i=0;i<q;i++) { if(icount[i]==0) continue; if(num%n!=0) if(isqure[itable[num-1]][1]!=isqure[i][3]) continue; if(num>=n) if(isqure[itable[num-n]][2]!=isqure[i][0]) continue; itable[num]=i; icount[i]--; //if(dfs(num+1)==1) return 1; dfs(num+1); icount[i]++; } return ; } int main() { //freopen("in.txt","r",stdin); int ans=1; while(scanf("%d",&n)!=EOF&&n) { flag=q=0; int top,right,bottm,left; for(int i=0;i<n*n;i++) { scanf("%d%d%d%d",&top,&right,&bottm,&left); int j=0; for(j=0;j<q;j++) { if(isqure[j][0]==top && isqure[j][1]==right && isqure[j][2]==bottm && isqure[j][3]==left) { icount[j]++; break; } } if(j==q) { isqure[j][0]=top; isqure[j][1]=right; isqure[j][2]=bottm; isqure[j][3]=left; q++; icount[j]=1; } } dfs(0); if(ans-1) printf("\n"); printf("Game %d: ",ans++); if(flag) printf("Possible\n"); else printf("Impossible\n"); } }
相关文章推荐
- vim 在linux下中如何设置显示行数
- 分类——LDA、QDA
- Openstack nova service 启动过程
- 找对英语学习方法的第一本书之:标准发音
- MySQL mysqldump 原理浅析
- 怎么样做内容才不会走火入魔?
- 怎么样做内容才不会走火入魔?
- CentOS6下安装Python
- 关于设置http响应头connection的作用
- JAVA_ 网络编程,写一个可以上传文件的服务器和客户端
- Spring JdbcTemplate
- 使用zip包离线安装Android SDK,并使用Unity发布apk
- 脚本通过snmp信息获取接口流量
- 公布源代码的大神主页
- shell序列和nohup &
- poj 2253 Frogger和 poj 2485 Highways
- 类的继承
- OC学习笔记01-类的声明实现与对象创建,方法声明实现与调用及传参
- SQL on Haoop/Spark
- 二叉堆