2015-03-25 22:14:58
思路:大模拟... 首先用floodfill判出每一个连通块,然后就是暴力枚举每个块的8个状态了... 写的超级暴力...
一开始MLE,把数组从int改到bool过了。后来TLE,加了一个剪枝(如果两个连通块内1的个数不等直接确定不一致)就过了。
关于8个状态:初始状态旋转 0°、90°、180°、270°
(overturn)初始状态镜面对称后旋转 0°、90°、180°、270°
1 /* 2 ID:naturec1 3 PROG: starry 4 LANG: C++ 5 */ 6 #include <cstdio> 7 #include <cstring> 8 #include <cstdlib> 9 #include <cmath> 10 #include <vector> 11 #include <map> 12 #include <set> 13 #include <stack> 14 #include <queue> 15 #include <string> 16 #include <iostream> 17 #include <algorithm> 18 using namespace std; 19 20 #define MEM(a,b) memset(a,b,sizeof(a)) 21 #define REP(i,n) for(int i=0;i<(n);++i) 22 #define FOR(i,a,b) for(int i=(a);i<=(b);++i) 23 #define getmid(l,r) ((l) + ((r) - (l)) / 2) 24 #define MP(a,b) make_pair(a,b) 25 26 typedef long long ll; 27 typedef pair<int,int> pii; 28 const int INF = (1 << 30) - 1; 29 30 int W,H,clu_cnt,stx,sty; 31 int id[110][110]; 32 char g[110][110]; 33 int dir[8][2] = {{-1,-1},{-1,0},{-1,1},{0,-1},{0,1},{1,-1},{1,0},{1,1}}; 34 35 struct Cluster{ 36 bool mp[110][110]; 37 int num; 38 }clu[510]; 39 40 void Dfs(int x,int y){ 41 clu[clu_cnt].mp[x][y] = 1; 42 clu[clu_cnt].num++; 43 id[x][y] = clu_cnt; 44 REP(i,8){ 45 int tx = x + dir[i][0]; 46 int ty = y + dir[i][1]; 47 if(tx < 0 || tx >= H || ty < 0 || ty >= W 48 || g[tx][ty] == '0' || id[tx][ty] != -1) continue; 49 Dfs(tx,ty); 50 } 51 } 52 53 void Move(bool graph[110][110]){ 54 int minx = INF,miny = INF; 55 bool tmp[110][110] = {0}; 56 REP(i,H) REP(j,W) if(graph[i][j]){ 57 minx = min(minx,i); 58 miny = min(miny,j); 59 } 60 REP(i,H) REP(j,W) if(graph[i][j]) tmp[i - minx][j - miny] = 1; 61 memcpy(graph,tmp,sizeof(tmp)); 62 } 63 64 bool Judge(bool g1[110][110],bool g2[110][110]){ 65 REP(i,H) REP(j,W) if(g1[i][j] ^ g2[i][j]) return false; 66 return true; 67 } 68 69 bool Check(int a,int b){ 70 if(clu[a].num != clu[b].num) return false; 71 72 bool tmp[110][110]; 73 if(Judge(clu[a].mp,clu[b].mp)) return true; 74 75 //CW 90 76 MEM(tmp,0); 77 REP(i,H) REP(j,W) if(clu[a].mp[i][j]) tmp[j][W - i - 1] = 1; 78 Move(tmp); 79 if(Judge(tmp,clu[b].mp)) return true; 80 //CW 180 81 MEM(tmp,0); 82 REP(i,H) REP(j,W) if(clu[a].mp[i][j]) tmp[H - i - 1][W - j - 1] = 1; 83 Move(tmp); 84 if(Judge(tmp,clu[b].mp)) return true; 85 //CW 270 86 MEM(tmp,0); 87 REP(i,H) REP(j,W) if(clu[a].mp[i][j]) tmp[H - j - 1][i] = 1; 88 Move(tmp); 89 if(Judge(tmp,clu[b].mp)) return true; 90 //overturn -------------------------------------- 91 REP(i,H) REP(j,W / 2) if(clu[a].mp[i][j]) 92 swap(clu[a].mp[i][j],clu[a].mp[i][W - j - 1]); 93 Move(clu[a].mp); 94 if(Judge(clu[a].mp,clu[b].mp)) return true; 95 //CW 90 96 MEM(tmp,0); 97 REP(i,H) REP(j,W) if(clu[a].mp[i][j]) tmp[j][W - i - 1] = 1; 98 Move(tmp); 99 if(Judge(tmp,clu[b].mp)) return true; 100 //CW 180 101 MEM(tmp,0); 102 REP(i,H) REP(j,W) if(clu[a].mp[i][j]) tmp[H - i - 1][W - j - 1] = 1; 103 Move(tmp); 104 if(Judge(tmp,clu[b].mp)) return true; 105 //CW 270 106 MEM(tmp,0); 107 REP(i,H) REP(j,W) if(clu[a].mp[i][j]) tmp[H - j - 1][i] = 1; 108 Move(tmp); 109 if(Judge(tmp,clu[b].mp)) return true; 110 111 return false; 112 } 113 114 int main(){ 115 freopen("starry.in","r",stdin); 116 freopen("starry.out","w",stdout); 117 MEM(id,-1); 118 scanf("%d%d",&W,&H); 119 REP(i,H) scanf("%s",g[i]); 120 REP(i,H) REP(j,W) if(g[i][j] == '1'){ 121 if(id[i][j] != -1) continue; 122 stx = i,sty = j; 123 Dfs(i,j); 124 clu_cnt++; 125 } 126 REP(i,clu_cnt) Move(clu[i].mp); 127 int tot = 0,tag[510] = {0}; 128 REP(i,clu_cnt){ 129 if(tag[i]) continue; 130 tag[i] = ++tot; 131 FOR(j,i + 1,clu_cnt - 1) if(Check(i,j)){ 132 tag[j] = tag[i]; 133 } 134 } 135 REP(i,H){ 136 REP(j,W){ 137 if(g[i][j] == '0') printf("0"); 138 else printf("%c",'a' + tag[id[i][j]] - 1); 139 } 140 puts(""); 141 } 142 return 0; 143 }