HDU 5374 Tetris 俄罗斯方块 模拟
2015-08-23 10:03
288 查看
这道题是喜闻乐见的大模拟题。
题目大意:在一个9X12的格子中玩俄罗斯方块,给定所有可能的方块形态,给定方块的掉落顺序,给定操作,w表示旋转,a表示左移,b表示右移,d表示下落一格(实际下落两格),p表示pass(即下落一格),输入数据保证不会GameOver,求最后的分数。
题意虽然简单,但是由于编程复杂度等众多原因,考场上写的人不多。这里有几个可以简化代码的trick,由于旋转最大循环节为4,方块最大长宽也为4,那么我们可以把每一种方块的形态用4*4*4的数组存下来,这样判断以及旋转操作都很容易实现;还有就是方块在移动过程中,只需把基点即左下角的点的坐标记下来,不需要每操作都把当前状态表示出来。
虽然我考场上用了这俩技巧,然而还是没有调出来哪里写错了,考完以后发现判断消除行的时候要从上往下枚举...非常可惜。
题目大意:在一个9X12的格子中玩俄罗斯方块,给定所有可能的方块形态,给定方块的掉落顺序,给定操作,w表示旋转,a表示左移,b表示右移,d表示下落一格(实际下落两格),p表示pass(即下落一格),输入数据保证不会GameOver,求最后的分数。
题意虽然简单,但是由于编程复杂度等众多原因,考场上写的人不多。这里有几个可以简化代码的trick,由于旋转最大循环节为4,方块最大长宽也为4,那么我们可以把每一种方块的形态用4*4*4的数组存下来,这样判断以及旋转操作都很容易实现;还有就是方块在移动过程中,只需把基点即左下角的点的坐标记下来,不需要每操作都把当前状态表示出来。
虽然我考场上用了这俩技巧,然而还是没有调出来哪里写错了,考完以后发现判断消除行的时候要从上往下枚举...非常可惜。
14473767 | 2015-08-12 11:19:26 | Accepted | 5374 | 0MS | 1412K | 2027 B | G++ | Kurama |
#include <cstdio> #include <cstdlib> #include <cstring> #define MAXN 1001 using namespace std; int order[MAXN],n,no,st,X,Y,score; //order为方块下落顺序,no表示该方块处于第几种旋转状态 //X,Y为现在的位置,score统计分数 bool Brick[3][4][4][4]={ { {{1,1,0,0},{1,1,0,0},{0,0,0,0},{0,0,0,0}}, {{1,1,0,0},{1,1,0,0},{0,0,0,0},{0,0,0,0}}, {{1,1,0,0},{1,1,0,0},{0,0,0,0},{0,0,0,0}}, {{1,1,0,0},{1,1,0,0},{0,0,0,0},{0,0,0,0}} },{ {{1,0,0,0},{1,0,0,0},{1,0,0,0},{1,0,0,0}}, {{1,1,1,1},{0,0,0,0},{0,0,0,0},{0,0,0,0}}, {{1,0,0,0},{1,0,0,0},{1,0,0,0},{1,0,0,0}}, {{1,1,1,1},{0,0,0,0},{0,0,0,0},{0,0,0,0}}, },{ {{1,1,1,0},{1,0,0,0},{0,0,0,0},{0,0,0,0}}, {{1,0,0,0},{1,0,0,0},{1,1,0,0},{0,0,0,0}}, {{0,0,1,0},{1,1,1,0},{0,0,0,0},{0,0,0,0}}, {{1,1,0,0},{0,1,0,0},{0,1,0,0},{0,0,0,0}}} }; //为了方便我们将所有类型的方块存成4*4 char oper[MAXN]; //操作字符串 bool dB,tetris[20][20]; //dB表示是否有下落完全的方块,tetris保存每个方块的最后状态 void Fresh(){ for(int i=0;i<4;i++) for(int j=0;j<4;j++) if(Brick[order[no]][st][i][j]) tetris[Y+i][X+j]=true; } //更新状态 bool Attempt(char op){ int x=X,y=Y,s=st,ty=order[no]; if(op=='w')s=(st+1)%4;else if(op=='s')y--;else if(op=='d')x++;else if(op=='a')x--; if(y==0 || x==0)return false; for(int i=0;i<4;i++) for(int j=0;j<4;j++) if(Brick[ty][s][i][j]) if(x+j>9 || tetris[y+i][x+j])return false; X=x;Y=y;st=s; return true; } //尝试操作,若操作不合法则忽略 bool check(int r){ for(int i=1;i<=9;i++)if(!tetris[r][i])return false; return true; } //检查是否可以消除 void delet(int r){ for(int i=r;i<=12;i++) for(int j=1;j<=9;j++)tetris[i][j]=tetris[i+1][j]; } //消除满行 void simulate(char op){ if(!dB){X=4,Y=9,st=0;dB=true;} if(op!='p')Attempt(op); if(Attempt('s'))return; // else{ Fresh(); dB=false; no++; for(int i=12;i>=1;i--) if(check(i)){ delet(i); score++; } } } //模拟操作 int main() { int t; scanf("%d",&t); for(int casen=1;casen<=t;casen++){ memset(tetris,0,sizeof tetris); no=score=0;dB=false; scanf("%d%s",&n,oper); for(int i=0;i<n;i++)scanf("%d",&order[i]); int len=strlen(oper); for(int i=0;i<len;i++)simulate(oper[i]); printf("Case %d: %d\n",casen,score); } return 0; }
相关文章推荐
- Transformation 能将 Windows XP/Server 2003 操作系统,完美地模拟成 Windows Vista 的软件
- 用javascript和css模拟select的脚本
- PHP模拟asp.net的StringBuilder类实现方法
- javascript用层模拟可移动的小窗口
- 自编jQuery插件实现模拟alert和confirm
- PHP模拟asp中response类实现方法
- javascript 模拟点击广告
- JQuery中模拟image的ajaxPrefilter与ajaxTransport处理
- php实现模拟post请求用法实例
- JavaScript实现MIPS乘法模拟的方法
- 模拟xcopy的函数
- php模拟服务器实现autoindex效果的方法
- C# SendInput 模拟鼠标操作的实现方法
- PHP模拟登陆163邮箱发邮件及获取通讯录列表的方法
- JS模拟并美化的表单控件完整实例
- php模拟登陆的实现方法分析
- php模拟用户自动在qq空间发表文章的方法
- php 模拟 asp.net webFrom 按钮提交事件实例
- php模拟post提交数据的方法
- JavaScript模拟重力状态下抛物运动的方法