Rank of Tetris 【HDU - 1811】【并查集+拓扑排序】

题目链接


  思维的确是有点巧妙了,我们需要用到并查集和拓扑排序,一开始的时候,我看到这类题,会不自觉地和种类并查集联系起来,但是这道题又有不同的地方,它的种类个数不固定,所以说我们没法用种类并查集来思考,于是就想到建一个有向图,我们把相等的先处理掉,反正相等的不会影响到我们最后的排序,所以,相等的就直接用并查集连立放到同一棵并查集的树上去,然后我们对所有树的根进行大小的排列处理建立有向图,会发现建立的图可以用拓扑来一一排除做法,我们如果最后排不掉所有的点,就说明这里有环,而有环就说明有地方的大小错了,而如果有一次,我们有两个节点要同时处理,就是有时候queue<>中的存放的值>1就说明这两个节点没有相互间的关系,说明有不确定节点,而最后如果遍历完,就说明是OK的解。


  我的做法或许会看上去有些繁琐(下面就是代码),因为我加了个map来去除重边的干扰(其实有没有都一样),只是为了queue<>的时候好处理些,然后我这里加边的方式是用的是链式前向星,所以会代码长度长些。


#include <iostream>
#include <cstdio>
#include <cmath>
#include <string>
#include <cstring>
#include <algorithm>
#include <limits>
#include <vector>
#include <stack>
#include <queue>
#include <set>
#include <map>
#define lowbit(x) ( x&(-x) )
#define pi 3.141592653589793
#define e 2.718281828459045
using namespace std;
typedef unsigned long long ull;
typedef long long ll;
const int maxN=10005;
int N, M, root[maxN], head[maxN<<2], cnt, point, degree[maxN];
bool flag;
map<pair<int, int>, bool> mp;
struct eddge
{
    int no, to;
    char state;
    eddge(int a=0, int b=0, char c=NULL):no(a), to(b), state(c) {}
}ship[maxN<<1];
struct node
{
    int nex, to, val;
    node(int a=-1, int b=0, int c=0):nex(a), to(b), val(c) {}
}edge[maxN<<1];
void addEddge(int u, int v, int val)
{
    edge[cnt]=node(head[u], v, val);
    head[u]=cnt++;
}
queue<int> Q;
void init()
{
    flag=false;
    mp.clear();
    while(!Q.empty()) Q.pop();
    cnt=0;  point=N;
    memset(head, -1, sizeof(head));
    memset(degree, 0, sizeof(degree));
    for(int i=0; i<N; i++) { root[i]=i; }
}
int fid(int x) { return x==root[x]?x:(root[x]=fid(root[x])); }
void mix(int x, int y)
{
    int u=fid(x), v=fid(y);
    if(u!=v)
    {
        root[u] = v;
        point--;
    }
}
void bfs()
{
    while(!Q.empty())
    {
        if(Q.size()>1) flag=true;
        int now=Q.front();  Q.pop();
        for(int u=head[now]; u!=-1; u=edge[u].nex)
        {
            int v=edge[u].to;
            degree[v]--;
            if(degree[v]==0)
            {
                Q.push(v);
                point--;
            }
        }
    }
}
int main()
{
    while(scanf("%d%d", &N, &M)!=EOF)
    {
        init();
        for(int i=1; i<=M; i++)
        {
            scanf("%d %c %d", &ship[i].no, &ship[i].state, &ship[i].to);
            if(ship[i].state == '=')
            {
                mix(ship[i].no, ship[i].to);
            }
        }
        for(int i=1; i<=M; i++)
        {
            if(ship[i].state == '=') continue;
            if(ship[i].state == '<')
            {
                if(mp[make_pair(fid(ship[i].to), fid(ship[i].no))]) continue;
                mp[make_pair(fid(ship[i].to), fid(ship[i].no))]=true;
                addEddge(fid(ship[i].to), fid(ship[i].no), 1);
                degree[fid(ship[i].no)]++;
            }
            else
            {
                if(mp[make_pair(fid(ship[i].no), fid(ship[i].to))]) continue;
                mp[make_pair(fid(ship[i].no), fid(ship[i].to))]=true;
                addEddge(fid(ship[i].no), fid(ship[i].to), 1);
                degree[fid(ship[i].to)]++;
            }
        }
        for(int i=0; i<N; i++)
        {
            if(degree[fid(i)]==0 && root[i]==i)
            {
                Q.push(fid(i));
                point--;
            }
        }
        bfs();
        if(point>0) printf("CONFLICT\n");
        else if(flag) printf("UNCERTAIN\n");
        else printf("OK\n");
    }
    return 0;
}

 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
好的,下面是俄罗斯方块的类UML图: ``` +----------------+ +-------------------+ | Tetris | | Tetrominoes | +----------------+ +-------------------+ | - gameBoard | | - shape | | - score | | - position | | - currentPiece | | - orientation | | - nextPiece | +-------------------+ | - timer | +----------------+ | + startGame() | | + pauseGame() | | + resumeGame() | | + gameOver() | | + moveLeft() | | + moveRight() | | + rotateCW() | | + rotateCCW() | | + drop() | | + updateScore()| +----------------+ +-------------------+ | Tetromino | +-------------------+ | - shape | | - position | | - orientation | | - color | +-------------------+ | + rotateCW() | | + rotateCCW() | | + moveLeft() | | + moveRight() | | + moveDown() | | + getShape() | | + getPosition() | | + getOrientation()| | + getColor() | +-------------------+ +-------------------+ | GameBoard | +-------------------+ | - width | | - height | | - cells | +-------------------+ | + isGameOver() | | + clearLines() | | + getCellAt() | | + setCellAt() | | + clearCellAt() | | + getFilledLines()| | + getWidth() | | + getHeight() | +-------------------+ ``` 其中,`Tetris` 类表示整个游戏,包括游戏的状态、分数、当前方块、下一个方块以及游戏计时器等。`Tetromino` 类表示俄罗斯方块中的一个方块,包括方块的形状、位置、方向以及颜色等。`GameBoard` 类表示游戏面板,包括面板的宽度、高度以及面板上的方块等。 以上是俄罗斯方块的类UML图,您可以参考这个图来实现您的程序。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Wuliwuliii

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值