[Elite 2008 Dec USACO]Jigsaw Puzzles
#include <iostream> #include <cstdio> #include <cstring> using namespace std; #define Up num[0] #define Right num[1] #define Down num[2] #define Left num[3] char ca,cb,cc,cd; int r,c,rc; bool v[110]; class Jigsaw { public: int serialNumber; char num[4]; public: void readIn() { scanf("%d%*c%c%*c%c%*c%c%*c%c%*c",&serialNumber,num,num+1,num+2,num+3); } void printOut() { printf("%d %c %c %c %c\n",serialNumber,num[0],num[1],num[2],num[3]); } int checkCorner() { int i; for (i=0; i<4; i++) { if (num[i] == '0' && num[(i+1)%4] == '0') return i; } return -1; } int checkSuit2c() { int i; for (i=0; i<4; i++) { if (num[i] == ca && num[(i+1)%4] == cb) return i; } return -1; } int checkSuit3c() { int i; for (i=0; i<4; i++) { if (num[i] == ca && num[(i+1)%4] == cb && num[(i+2)%4] == cc) return i; } return -1; } int checkSuit4c() { int i; for (i=0; i<4; i++) { if (num[i] == ca && num[(i+1)%4] == cb && num[(i+3)%4] == cc) return i; } return -1; } }; Jigsaw js[110]; Jigsaw tb[11][11]; bool check_and_rotate(int x,int y,int d) { int t; if (x == 0 && y == 0) { t=js[d].checkCorner(); if (t == -1) return false; tb[x][y].serialNumber=js[d].serialNumber; tb[x][y].Left=js[d].num[t]; tb[x][y].Up=js[d].num[(t+1)%4]; tb[x][y].Right=js[d].num[(t+2)%4]; tb[x][y].Down=js[d].num[(t+3)%4]; return true; } if (x == 0) cb='0'; else cb=tb[x-1][y].Down; if (y == 0) ca='0'; else ca=tb[x][y-1].Right; if (y == c-1) { cc='0'; t=js[d].checkSuit3c(); if (t == -1) return false; tb[x][y].serialNumber=js[d].serialNumber; tb[x][y].Left=js[d].num[t]; tb[x][y].Up=js[d].num[(t+1)%4]; tb[x][y].Right=js[d].num[(t+2)%4]; tb[x][y].Down=js[d].num[(t+3)%4]; return true; } else if (x == r-1) { cc='0'; t=js[d].checkSuit4c(); if (t == -1) return false; tb[x][y].serialNumber=js[d].serialNumber; tb[x][y].Left=js[d].num[t]; tb[x][y].Up=js[d].num[(t+1)%4]; tb[x][y].Right=js[d].num[(t+2)%4]; tb[x][y].Down=js[d].num[(t+3)%4]; return true; } else { t=js[d].checkSuit2c(); if (t == -1) return false; tb[x][y].serialNumber=js[d].serialNumber; tb[x][y].Left=js[d].num[t]; tb[x][y].Up=js[d].num[(t+1)%4]; tb[x][y].Right=js[d].num[(t+2)%4]; tb[x][y].Down=js[d].num[(t+3)%4]; return true; } return false; } bool DFS(int x,int y) { int i,j; if (y == c) { x++; y=0; if (x == r) { for (i=0; i<r; i++) { for (j=0; j<c; j++) { tb[i][j].printOut(); } } return true; } return DFS(x,y); } for (i=0; i<rc; i++) { if (v[i] == true) continue; if (check_and_rotate(x,y,i) == true) { v[i]=true; if (DFS(x,y+1) == true) return true; v[i]=false; } } return false; } int main() { int i,j; scanf("%d%d",&r,&c); rc=r*c; for (i=0; i<rc; i++) { js[i].readIn(); v[i]=false; } DFS(0,0); return 0; }
USACO Elite 2008 December Competition Silver
题意:给你一些正方形的拼图碎块,每个碎块有四个边,每边都有一个记号,分别是小写字母a-z。其中没有标记的边,也就是边界的边用'0'标记。题目给定一个矩阵,把这些碎块放进去,要求每个边相接的记号必须一样,边界上的边必须是'0'。
解法:DFS。这个操作起来还是挺麻烦的,做处理的时候要小心一些。