USACO 5.1 Starry Night(模拟)

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 }

 

posted @ 2015-03-25 22:20  Naturain  阅读(151)  评论(0编辑  收藏  举报