zoukankan      html  css  js  c++  java
  • HDU 5374 Tetris (2015年多校比赛第7场)

    1.题目描写叙述:点击打开链接

    2.解题思路:本题要求模拟俄罗斯方块游戏。然而比赛时候写了好久还是没过。

    后来补题发现原来是第四步的逻辑实现写错了。。。

    题目中要求假设一整行能够消除,那么仍然运行该步。否则才回到第一步。可是我的代码却是不论能否够消除,都回到第一步。。

    。补题时候还发现一个地方我的理解出错了。。

    (可能是我脑洞真的有点大)。题目中说假设一整行能够消除,那么它上面的方格要下落。我的理解是下落的方格要一直降落到第一行或者某个支撑物上,最后发现依照这样写,例子都算不正确==。调试了一下别人的代码才发现是仅仅下落一个。无论它以下是否有支撑物==。或许是非常久都没玩过的原因吧,玩法都忘了。。看来模拟题还是要弄清细节才干动手。否则真是WARush。


    本题的实现能够考虑使用常量数组。通过题目描写叙述能够知道一共同拥有7种不同的状态。如果我们以special square为參考,那么每一个状态相对于special square的坐标是能够唯一确定的,最好还是用dx[7][4],dy[7][4]分开表示。另一个技巧。移动或者旋转的时候仅仅须要用一个vector来存储操作后的全部坐标就可以。不必每次真的画到图上,仅仅须要画出终于的位置就可以。

    3.代码:

    #define _CRT_SECURE_NO_WARNINGS
    #include<iostream>
    #include<algorithm>
    #include<string>
    #include<sstream>
    #include<set>
    #include<vector>
    #include<stack>
    #include<map>
    #include<queue>
    #include<deque>
    #include<cstdlib>
    #include<cstdio>
    #include<cstring>
    #include<cmath>
    #include<ctime>
    #include<cctype>
    #include<functional>
    using namespace std;
    
    #define me(s) memset(s,0,sizeof(s))
    #define pb push_back
    typedef long long ll;
    typedef unsigned int uint;
    typedef unsigned long long ull;
    typedef pair <int, int> P;
    
    
    
    const int N = 15;
    
    int dx[7][4] = { { 0, 0, 1, 1 }, { 0, 0, 0, 0 }, { 0, 1, 2, 3 },    
    { 0, 0, 1, 2 }, { 0, 0, 0, 1 }, { 0, 1, 2, 2 }, { 0, 1, 1, 1 }
    };
    int dy[7][4] = { { 0, 1, 0, 1 }, { 0, 1, 2, 3 }, { 0, 0, 0, 0 },
    { 0, 1, 0, 0 }, { 0, 1, 2, 2 }, { 1, 1, 1, 0 }, { 0, 0, 1, 2 }
    };
    int first[] = { 0, 1, 3 };//每一类俄罗斯方块的初始状态的编号
    int g[N][N];
    int a[100000];
    vector<P>pos;//用一个vector存储每次操作完的全部坐标
    int sx, sy, cur;//(sx,sy)表示special square的坐标。cur表示当前的状态(0~6的某一种)
    
    void init(int id)//初始化状态
    {
    	pos.clear();
    	sx = 4, sy = 9, cur = first[id];
    	for (int i = 0; i < 4; i++)
    		pos.push_back(P(sx + dx[cur][i], sy + dy[cur][i]));
    }
    
    bool inside(int x, int y)
    {
    	return x >= 1 && x <= 9 && y >= 1 && y <= 12;
    }
    
    bool can_move(int dx, int dy)
    {
    	int len = pos.size();
    	for (int i = 0; i < len; i++)
    	{
    		int nx = pos[i].first + dx, ny = pos[i].second + dy;
    		if (!inside(nx, ny) || g[nx][ny])return false;
    	}
    	return true;
    }
    
    bool can_rotate(int type)
    {
    	if (type == 1)
    	{
    		int goal = 3 - cur;
    		for (int i = 0; i < 4; i++)
    		if (!inside(sx + dx[goal][i], sy + dy[goal][i]) || g[sx + dx[goal][i]][sy + dy[goal][i]])return false;
    	}
    	else if (type == 2)
    	{
    		int goal = (cur == 6) ? 3 : cur + 1;
    		for (int i = 0; i < 4; i++)
    		if (!inside(sx + dx[goal][i], sy + dy[goal][i]) || g[sx + dx[goal][i]][sy + dy[goal][i]])return false;
    	}
    	return true;
    }
    
    void move(int dx, int dy)
    {
    	int len = pos.size();
    	for (int i = 0; i < len; i++)
    	{
    		int nx = pos[i].first + dx, ny = pos[i].second + dy;
    		pos[i] = P(nx, ny);
    	}
    	sx += dx, sy += dy;
    }
    
    void rotate(int type)
    {
    	if (!type)return;
    	else if (type == 1)
    	{
    		cur = 3 - cur;  //更新状态
    		int len = pos.size();
    		pos.clear();
    		for (int i = 0; i < 4; i++)
    			pos.push_back(P(sx + dx[cur][i], sy + dy[cur][i]));
    	}
    	else if (type == 2)
    	{
    		cur = (cur == 6) ?

    3 : cur + 1; pos.clear(); for (int i = 0; i < 4; i++) pos.push_back(P(sx + dx[cur][i], sy + dy[cur][i])); } } void draw() { int len = pos.size(); for (int i = 0; i < len; i++) { int x = pos[i].first, y = pos[i].second; g[x][y] = 1; } } void operate(char op, int id) { if (op == 'w') { if (can_rotate(id))rotate(id); } else if (op == 'a') { if (can_move(-1, 0))move(-1, 0); } else if (op == 's') { if (can_move(0, -1))move(0, -1); } else if (op == 'd') { if (can_move(1, 0))move(1, 0); } } int can_fall() { int y; for (y = 1; y <= 12; y++) { int ok = 1; for (int i = 1; i <= 9; i++) if (!g[i][y]){ ok = 0; break; } if (ok)return y; } return 0; } int main() { int T; int rnd = 0; scanf("%d", &T); while (T--) { int n; string cmd; scanf("%d", &n); cin >> cmd; me(g); me(a); pos.clear(); int len = cmd.length(); int ans = 0, p = 0; for (int i = 0; i < n; i++)scanf("%d", &a[i]); for (int i = 0; i < n; i++) { init(a[i]); while (1) { if (p < len) operate(cmd[p++], a[i]); if (can_move(0, -1)) move(0, -1);//不能下落 else break; } draw();//画出终于的位置 int q, ok; while ((q = can_fall())>0)//直到没有完整的一行时才退出 { ans++; for (int i = 1; i <= 9; i++) { g[i][q] = 0; for (int j = q + 1; j <= 12; j++) if (g[i][j]) g[i][j - 1] = 1, g[i][j] = 0; //仅仅下落一格。

    。。

    不要多想 } } } printf("Case %d: %d ", ++rnd, ans); } }


  • 相关阅读:
    移动端轮播图
    移动端的注册页面
    点击显示或者消失的效果(手风琴效果)
    canvas的一些简单绘制方法
    用canvas来手动绘画
    canvas标签的运用
    Html5新标签解释及用法
    最近的心得
    浅谈正则表达式
    P3197 [HNOI2008]越狱
  • 原文地址:https://www.cnblogs.com/lxjshuju/p/7221608.html
Copyright © 2011-2022 走看看