思路:
先写好了几个函数。旋转,四种操作,判断是否可以进行合并消除
题中有好几处要考虑的细节问题,如
自然下落到底部时不进行合并的判断,而是当自然下落非法时才判断
如果消除一行,这一行上面的所以方块只会下落一行,不存在直接下落到底部的情况
比赛时题意没有理解好,错了这两个地方。。
还有一些写法上的错误,这种左右移动的题目坐标还是要从1开始,方便许多
左右移动,如果非法要复原的时候,复原的操作要与移动操作 完全相反,并且这个范围要从0开始,因为移动的时候可能移动到非法的位置。
赛后看了标程,各种优美简洁的代码。模拟能力还有待加强。
#include<iostream> #include<cmath> #include<algorithm> #include<cstring> #include<string> #include<cstdio> #include<vector> #define pb push_back #define debug puts("====================="); //#pragma comment(linker, "/STACK:1024000000,1024000000") using namespace std; typedef long long ll; int t; int Map[20][20]; //记录整体 int updata[20][20]; //记录当前掉落方块 char ch[1111]; int a[1111]; int n; int chong() //判断是否有非法操作 { int sum = 0; for(int i=1; i<=12; i++) for(int j=1; j<=9; j++) if(updata[i][j]) sum++; if(sum!=4) return 0; for(int i=1; i<=12; i++) for(int j=1; j<=9; j++) if(updata[i][j]+Map[i][j]>1) return 0; return 1; } int zhuan(int type,int x,int y) //旋转 { if(type==1) { swap(updata[x-1][y],updata[x][y+1]); swap(updata[x-2][y],updata[x][y+2]); swap(updata[x-3][y],updata[x][y+3]); if(!chong()) //如果非法,再转回来 { swap(updata[x-1][y],updata[x][y+1]); swap(updata[x-2][y],updata[x][y+2]); swap(updata[x-3][y],updata[x][y+3]); } } else if(type==2) { if(updata[x][y]==0) ///3->4 { swap(updata[x-1][y],updata[x-2][y+1]); swap(updata[x-1][y+2],updata[x][y+1]); swap(updata[x][y+2],updata[x][y]); if(!chong()) { swap(updata[x-1][y],updata[x-2][y+1]); swap(updata[x-1][y+2],updata[x][y+1]); swap(updata[x][y+2],updata[x][y]); } } else { if(updata[x-1][y]&&updata[x][y+1]) ///1->2 { swap(updata[x][y+1],updata[x-2][y]); swap(updata[x][y+2],updata[x-2][y+1]); if(!chong()) { swap(updata[x][y+1],updata[x-2][y]); swap(updata[x][y+2],updata[x-2][y+1]); } } else if(updata[x-1][y]&&!updata[x][y+1]) ///2->3 { swap(updata[x][y],updata[x-1][y+1]); swap(updata[x-2][y],updata[x-1][y+2]); swap(updata[x-2][y+1],updata[x][y+2]); if(!chong()) { swap(updata[x][y],updata[x-1][y+1]); swap(updata[x-2][y],updata[x-1][y+2]); swap(updata[x-2][y+1],updata[x][y+2]); } } else if(!updata[x-1][y]&&updata[x][y+1]) ///4->1 { swap(updata[x-1][y+1],updata[x-1][y]); swap(updata[x-2][y+1],updata[x][y+2]); if(!chong()) { swap(updata[x-1][y+1],updata[x-1][y]); swap(updata[x-2][y+1],updata[x][y+2]); } } } } } int ctrl(char lei,int type) //控制上下左右 { if(lei=='w') { if(type==0) return 0; int xx,yy; xx = -9999; yy = 9999; for(int i=1; i<=12; i++) for(int j=1; j<=9; j++) if(updata[i][j]) xx = max(xx,i),yy = min(yy,j); //找到绿色的点,以这个点为基准 zhuan(type,xx,yy); } else if(lei=='a') { for(int i=1; i<=12; i++) for(int j=0; j<=10; j++) if(updata[i][j]) swap(updata[i][j],updata[i][j-1]); if(!chong()) //如果非法,再移回来 { for(int i=1; i<=12; i++) for(int j=10; j>=0; j--) if(updata[i][j]) swap(updata[i][j],updata[i][j+1]); } } else if(lei=='d') { for(int i=1; i<=12; i++) for(int j=10; j>=0; j--) if(updata[i][j]) swap(updata[i][j],updata[i][j+1]); if(!chong()) { for(int i=1; i<=12; i++) for(int j=0; j<=10; j++) if(updata[i][j]) swap(updata[i][j],updata[i][j-1]); } } else if(lei=='s') { for(int i=13; i>=1; i--) for(int j=1; j<=9; j++) if(updata[i][j]) swap(updata[i][j],updata[i+1][j]); if(!chong()) { for(int i=1; i<=13; i++) for(int j=1; j<=9; j++) if(updata[i][j]) swap(updata[i][j],updata[i-1][j]); } } return 1; } int score,tmp,jj,len; int di() //判断是否可以合并、消除 { int go = 1; for(int i=1; i<=11; i++) for(int j=1; j<=9; j++) { if(updata[i][j]&&updata[i+1][j]==0) { if(Map[i+1][j]) go = 0; } } for(int j=1; j<=9; j++) { if(updata[12][j]) go = 0; } if(go) return 0; for(int i=1; i<=12; i++) for(int j=1; j<=9; j++) { if(updata[i][j]) Map[i][j] = updata[i][j]; } while(1) { int flag = 0; int hang = 12; for(int i=1; i<=12; i++) { int sum = 0; if(Map[i][1]) { for(int j=1; j<=9; j++) sum+=Map[i][j]; } if(sum==9) { // cout<<"--------\n"; hang = i; flag = 1; score++; for(int j=1; j<=9; j++) Map[i][j] = 0; break; } } if(flag) { for(int i=hang-1; i>=1; i--) for(int j=1; j<=9; j++) if(Map[i][j]&&Map[i+1][j]==0) swap(Map[i][j],Map[i+1][j]); } else break; } return 1; } int main() { // freopen( "3.out","w",stdout ); cin>>t; int cs = 1; while(t--) { score = 0; scanf("%d%s",&n,ch); for(int i=0; i<n; i++) scanf("%d",&a[i]); memset(Map,0,sizeof(Map)); memset(updata,0,sizeof(updata)); jj = 0; len=strlen(ch); for(int i=0; i<n; i++) //下落的方块 { tmp = a[i]; memset(updata,0,sizeof(updata)); if(a[i]==0) { updata[4][4] = 1; updata[3][4] = 1; updata[4][5] = 1; updata[3][5] = 1; } else if(a[i]==1) { updata[4][4] = 1; updata[3][4] = 1; updata[2][4] = 1; updata[1][4] = 1; } else if(a[i]==2) { updata[4][4] = 1; updata[3][4] = 1; updata[4][5] = 1; updata[4][6] = 1; } for( ; jj<len; jj++) //操作编号 { if(ch[jj]!='p') ctrl(ch[jj],tmp); if(di()) //判断是否进行合并,消除 { jj++; break; } ctrl('s',tmp); //每次自然下落 } } printf("Case %d: %d\n",cs++,score); } return 0; }
版权声明:本文为博主原创文章,未经博主允许不得转载。
HDU5374 Tetris (2015年多校比赛第7场)大模拟
原文地址:http://blog.csdn.net/u013588639/article/details/47441929