例题7-12 UVA - 1343 The Rotation Game 旋转游戏(IDA*)
2016-05-04 00:22
465 查看
题目大意:
给一个棋盘,问最少进行几次旋转使得中间的数字全部相等!(并且字典序最小!)
思路:
借鉴了代码仓库,感觉写的很巧妙,简单记录一下!
大致思路:
用line [][] 二维数组给棋盘进行标号!
a[] 一维数组代表当前的棋盘中棋子的标号!
center[] 一维数组代表棋盘中间棋子的标号!
rev[]数组进行反转列 ,减少了很多代码!
先判断是否合法,合法的话直接输出。NO need。。。 还有数字!
否则进行迭代加深
迭代加深中要说的有两点:
1.move函数 move(i)是进行移动!
move(rev[i])是倒回来!很巧妙!
2.if (cur + geth() > maxd)return false; 这个意思代表 需要改的 + 已经改的大于maxd的话 直接return false;进行下一次迭代加深!
注意:
当一上来就合法时别忘了输出数字,,WA了不知道几遍了~~~
给一个棋盘,问最少进行几次旋转使得中间的数字全部相等!(并且字典序最小!)
思路:
借鉴了代码仓库,感觉写的很巧妙,简单记录一下!
大致思路:
用line [][] 二维数组给棋盘进行标号!
a[] 一维数组代表当前的棋盘中棋子的标号!
center[] 一维数组代表棋盘中间棋子的标号!
rev[]数组进行反转列 ,减少了很多代码!
先判断是否合法,合法的话直接输出。NO need。。。 还有数字!
否则进行迭代加深
迭代加深中要说的有两点:
1.move函数 move(i)是进行移动!
move(rev[i])是倒回来!很巧妙!
2.if (cur + geth() > maxd)return false; 这个意思代表 需要改的 + 已经改的大于maxd的话 直接return false;进行下一次迭代加深!
注意:
当一上来就合法时别忘了输出数字,,WA了不知道几遍了~~~
#include<cstdio> #include<cstring> #include<algorithm> using namespace std; const int maxn = 30; int line[maxn][maxn] = { {0, 2, 6, 11, 15, 20, 22}, // A; 0 {1, 3, 8, 12, 17, 21, 23}, // B; 1 {10, 9, 8, 7, 6, 5, 4}, // C; 2 {19, 18, 17, 16, 15, 14, 13}, // D; 3 }; const int rev[maxn] = {5, 4, 7, 6, 1, 0, 3, 2}; const int center[maxn] = {6, 7, 8, 11, 12, 15, 16, 17}; int a[maxn]; char s[10000]; int dif(int k){ int sum = 0; for (int i = 0; i < 8; ++i) if (a[center[i]] != k)++sum; return sum; } int geth(){ return min(min(dif(1),dif(2)),dif(3)); } void move(int k){ int temp = a[line[k][0]]; for (int i = 0; i <= 5; ++i) a[line[k][i]] = a[line[k][i+1]]; a[line[k][6]] = temp; } bool is_ok(){ for (int i = 1; i < 8; ++i) if (a[center[i]] != a[center[0]])return false; return true; } bool dfs(int cur,int maxd){ if (is_ok()){ s[cur] = 0; printf("%s\n",s); return true; } if (cur + geth() > maxd)return false;//需要改的+已经改了的 大于maxd return false; for (int i = 0; i < 8; ++i){ s[cur] = 'A' + i; move(i); if (dfs(cur+1,maxd))return true; move(rev[i]); } return false; } int main(){ for (int i = 4; i < 8; ++i) for (int j = 0; j < 7; ++j) line[i][j] = line[rev[i]][6-j]; while(scanf("%d",&a[0]) == 1 && a[0]){ for (int i = 1; i < 24; ++i)scanf("%d",&a[i]); if (is_ok()){printf("No moves needed\n%d\n",a[16]);continue;} for (int maxd = 0;; ++maxd){ if (dfs(0,maxd))break; } printf("%d\n",a[16]); } return 0; }
相关文章推荐
- 数据库拆分的几种方式
- mysql5.5提示Deprecated: mysql_query(): The mysql extension is deprecated
- 最短路 HDU 2544
- 疯狂java笔记3:集合类(1)
- java中关于try、catch、finally中的细节分析
- RecycleView的学习笔记
- hdu 1406 完数
- ViewFilpper
- Java获取当前时间的上一个月和下一个月,第一天和最后一天,任意时间的第一天和最后一天,任意时间上一个月和下一个月
- 设计模式学习--桥接模式
- MySQL 存储过程
- Ubuntu16.04 ext4格式硬盘挂载普通用户权限控制
- 【步兵 c++】 多态&虚函数
- 智能指针 weak_ptr
- 通过字符串获取资源ID
- 十天学会单片机Day5 IIC总线AT2402芯片(EEPROM)应用
- ios - block循环引用Demo示例
- js控制只能输入数字和小数点
- C++11 正则表达式——实例3
- Web前端和后端之区分,以及面临的挑战