[noip2011 d1t3] Mayan游戏
无脑码农题==
烦的是很多细节,把几个主要过程分开写,化整为零会清楚很多
1 #include<cstdio> 2 #include<cstring> 3 #include<cmath> 4 #include<algorithm> 5 using namespace std; 6 #define mxcol 12 7 int map[10][10]; 8 int goal; 9 struct data{ 10 int x,y,w; 11 }ans[10]; 12 int read(){ 13 int x=0; 14 char ch=getchar(); 15 while (ch<'0'||ch>'9') ch=getchar(); 16 while (ch>='0'&&ch<='9'){ 17 x=x*10+ch-'0'; 18 ch=getchar(); 19 } 20 return x; 21 } 22 bool empty(){ 23 for (int i=0;i<5;i++) 24 for (int j=0;j<7;j++) 25 if (map[i][j]) return 0; 26 return 1; 27 } 28 void DROP(){ 29 int time[10][10]; 30 memset(time,-1,sizeof(time)); 31 for (int x=0;x<5;x++){ 32 int num=0; 33 for (int y=0;y<7;y++) 34 if (map[x][y]) 35 time[x][num++]=y; 36 } 37 for(int x=0;x<5;x++) 38 for (int y=0;y<7;y++) 39 map[x][y]=time[x][y]==-1?0:map[x][time[x][y]]; 40 } 41 bool CLEAR(){ 42 bool flag=0; 43 //横 44 for (int i=0;i<3;i++) 45 for (int j=0;j<7;j++) 46 if (map[i][j]){ 47 int x; 48 for (x=i;x+1<5&&map[i][j]==map[x+1][j];x++); 49 if (x-i>=2){ 50 int nx; 51 for (nx=i;nx<=x;nx++){ 52 int up=j,down=j; 53 while (up+1<7&&map[nx][up+1]==map[i][j]) up++; 54 while (down-1>=0&&map[nx][down-1]==map[i][j]) down--; 55 if (up-down>=2){ 56 for (int ny=down;ny<=up;ny++) 57 map[nx][ny]=0; 58 } 59 } 60 for (nx=i;nx<=x;nx++) 61 map[nx][j]=0; 62 flag=1; 63 } 64 } 65 //竖 66 for (int i=0;i<5;i++) 67 for (int j=0;j<5;j++) 68 if (map[i][j]){ 69 int y; 70 for (y=j;y+1<7&&map[i][y+1]==map[i][j];y++); 71 if (y-j>=2){ 72 int ny; 73 for (ny=j;ny<=y;ny++){ 74 int left=i,right=i; 75 while (left>0&&map[left-1][ny]==map[i][j]) left--; 76 while (right+1<7&&map[right+1][ny]==map[i][j]) right++; 77 if (right-left>=2){ 78 for (int nx=left;nx<=right;nx++) 79 map[nx][ny]=0; 80 } 81 } 82 for (ny=j;ny<=y;ny++) 83 map[i][ny]=0; 84 flag=1; 85 } 86 } 87 return flag; 88 } 89 void dfs(int step){ 90 if (step>goal){ 91 if (empty()){//判断游戏结束 92 for (int i=1;i<=goal;i++) 93 if (ans[i].w) 94 printf("%d %d -1\n",ans[i].x+1,ans[i].y); 95 else 96 printf("%d %d 1\n",ans[i].x,ans[i].y); 97 exit(0); 98 } 99 return; 100 } 101 102 int time[mxcol]; 103 memset(time,0,sizeof(time)); 104 for (int i=0;i<5;i++) 105 for (int j=0;j<7;j++) 106 time[map[i][j]]++; 107 for (int i=1;i<=10;i++) 108 if (time[i]!=0&&time[i]<3) return;//剪枝:当某种颜色块数小于3时必然无解 109 110 for (int x=0;x<4;x++)//优先向右换;按字典序枚举 111 for (int y=0;y<7;y++) 112 if (map[x][y]!=map[x+1][y]){//两方块颜色不同时才交换 113 ans[step].x=x,ans[step].y=y; 114 ans[step].w=!map[x][y];//枚举的时候是从左往右,但也可能左边空右边有方块,此时标记将右边的方块向左移动 115 int tmp[10][10]; 116 memcpy(tmp,map,sizeof(tmp)); 117 swap(map[x][y],map[x+1][y]); 118 119 DROP(); 120 while (CLEAR()) DROP(); 121 //两个主要过程:上面的方块掉落;合法的方块消去 122 dfs(step+1); 123 124 ans[step].x=0,ans[step].y=0; 125 ans[step].w=0; 126 memcpy(map,tmp,sizeof(map)); 127 } 128 } 129 int main(){ 130 goal=read(); 131 memset(map,0,sizeof(map)); 132 for (int i=0;i<5;i++){ 133 for (int j=0;;j++){ 134 int u=read(); 135 if (!u) break; 136 map[i][j]=u; 137 } 138 } 139 dfs(1); 140 printf("-1\n"); 141 return 0; 142 }