POJ 1166 The Clocks 解题报告(高斯消元法 & 逆矩阵)
2013-08-09 20:40
429 查看
题目大意:9种操作可以让不同的种转动90度,求最小上升的操作方式。
解题报告:这题解法众多,也很有趣。可以BFS,DFS,9重循环暴搜也没问题= =。当然,为了学习还是用高斯消元法做的。
Discuss也有人讨论了,4不是质数,求解过程中不能模4,不一定有解的问题。按照我的理解,题目既然说了有唯一解,就不用考虑这个问题了。
另外,寻找当前列的对应行时不能选绝对值最大的,会WA。具体原因不详……代码如下:
当然,也可以事先求出转动矩阵的逆矩阵,直接求解= =代码如下:
解题报告:这题解法众多,也很有趣。可以BFS,DFS,9重循环暴搜也没问题= =。当然,为了学习还是用高斯消元法做的。
Discuss也有人讨论了,4不是质数,求解过程中不能模4,不一定有解的问题。按照我的理解,题目既然说了有唯一解,就不用考虑这个问题了。
另外,寻找当前列的对应行时不能选绝对值最大的,会WA。具体原因不详……代码如下:
#include <cstdio> #include <cstring> #include <algorithm> #include <math.h> using namespace std; int a[10][10]; int x[10]; bool free_x[10]; int sum; int Gauss(int equ,int var) { memset(x,0,sizeof(x)); memset(free_x,1,sizeof(free_x)); int k=0,col=0; while(k<equ && col<var) { if(a[k][col]==0) for(int i=k+1;i<equ;i++) if(a[i][col]) for(int j=col;j<=var;j++) swap(a[i][j],a[k][j]); if(a[k][col]==0) { col++; continue; } for(int i=k+1;i<equ;i++) if(a[i][col]) { int ta =a[i][col]; int tb =a[k][col]; for(int j=col;j<=var;j++) { a[i][j]=a[i][j]*tb-a[k][j]*ta; a[i][j]=(a[i][j]%4+4)%4; } } k++; col++; } for(int i=var-1;i>=0;i--) { int temp=a[i][var]; for(int j=i+1;j<var;j++) if(a[i][j]) temp-=a[i][j]*x[j]; temp=(temp%4+4)%4; for(x[i]=0;x[i]<=3;x[i]++) // 转5次和转1次没区别,所以只有4种 if((x[i]*a[i][i]%4+4)%4==temp) // 尝试解 break; x[i]%=4; sum+=x[i]; } return 0; } int main() { // freopen("in.txt","r",stdin); a[0][0]=a[1][0]=a[3][0]=a[4][0]=1; a[0][1]=a[1][1]=a[2][1]=1; a[1][2]=a[2][2]=a[4][2]=a[5][2]=1; a[0][3]=a[3][3]=a[6][3]=1; a[1][4]=a[3][4]=a[4][4]=a[5][4]=a[7][4]=1; a[2][5]=a[5][5]=a[8][5]=1; a[3][6]=a[4][6]=a[6][6]=a[7][6]=1; a[6][7]=a[7][7]=a[8][7]=1; a[4][8]=a[5][8]=a[7][8]=a[8][8]=1; for(int i=0;i<9;i++) { scanf("%d",&a[i][9]); a[i][9]=(4-a[i][9])%4; // 要转的次数 } Gauss(9,9); for(int j=0;j<9;j++) while(x[j]) { printf("%d",j+1); x[j]--; sum--; printf(sum>0?" ":"\n"); } }
当然,也可以事先求出转动矩阵的逆矩阵,直接求解= =代码如下:
// 逆矩阵 #include <cstdio> #include <cstring> using namespace std; int a[9][9]={ {3,2,3,2,2,1,3,1,0,}, {3,3,3,3,3,3,2,0,2,}, {3,2,3,1,2,2,0,1,3,}, {3,3,2,3,3,0,3,3,2,}, {3,2,3,2,1,2,3,2,3,}, {2,3,3,0,3,3,2,3,3,}, {3,1,0,2,2,1,3,2,3,}, {2,0,2,3,3,3,3,3,3,}, {0,1,3,1,2,2,3,2,3,}}; int x[9]; int res[9]; int main() { for(int i=0;i<9;i++) { scanf("%d",x+i); x[i]=(4-x[i])%4; } for(int i=0;i<9;i++) for(int j=0;j<9;j++) res[i]+=a[i][j]*x[j]; for(int i=0;i<9;i++) while(res[i]%4 && res[i]--) printf("%d ",i+1); puts(""); }
相关文章推荐
- pku 1166 the clocks 高斯消去法 解题报告
- POJ 1830 开关问题 解题报告(高斯消元法)
- POJ 1166&IOI 1994 The blocks 暴力枚举 解题报告
- POJ 2947 Widget Factory 解题报告(高斯消元法)
- POJ 1222 EXTENDED LIGHTS OUT 解题报告(高斯消元法)
- POJ 1166解题报告
- POJ 1753 Flip Game 解题报告(高斯消元法)
- POJ 1679 解题报告
- POJ - 2513 Colored Sticks解题报告(欧拉回路+并查集+字典树)
- poj2387解题报告(Dijkstra算法)
- 【解题报告】poj openjudge 拼写检查 pku数算mooc 检索
- POJ 3278解题报告(C语言版)//Catch That Cow
- POJ - 3414 Pots解题报告(输出路径的bfs)
- poj 2389 解题报告 大数乘法
- POJ 1379-Run Away解题报告
- POJ 1003 解题报告
- POJ 2253 解题报告
- POJ 1286 解题报告
- poj 2367 Genealogical tree 拓扑排序 解题报告
- poj 1469 COURSES 解题报告