#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 Silverios
題意:給你一些正方形的拼圖碎塊,每一個碎塊有四個邊,每邊都有一個記號,分別是小寫字母a-z。其中沒有標記的邊,也就是邊界的邊用'0'標記。題目給定一個矩陣,把這些碎塊放進去,要求每一個邊相接的記號必須同樣,邊界上的邊必須是'0'。ui
解法:DFS。這個操做起來仍是挺麻煩的,作處理的時候要當心一些。spa