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); } }


  • 相关阅读:
    CodeForces 660D Number of Parallelograms
    【POJ 1082】 Calendar Game
    【POJ 2352】 Stars
    【POJ 2481】 Cows
    【POJ 1733】 Parity Game
    【NOI 2002】 银河英雄传说
    【NOI 2015】 程序自动分析
    【POJ 1704】 Georgia and Bob
    【HDU 2176】 取(m堆)石子游戏
    【SDOI 2016】 排列计数
  • 原文地址:https://www.cnblogs.com/lxjshuju/p/7221608.html
Copyright © 2011-2022 走看看