【ZJOI2014】【BZOJ3519】消棋子

题目大意:消棋子是一个有趣的游戏。游戏在一个 rc 的棋盘上进行。棋盘的每个格 子,要么是空,要么是一种颜色的棋子。同一种颜色的棋子恰好有两个。每一轮, 玩家可以选择一个空格子 (x,y) ,并选择上下左右四个方向中的两个方向,如果 在这两个方向上均存在有棋子的格子,而且沿着这两个方向上第一个遇到的棋子 颜色相同,那么,我们将这两个棋子拿走,并称之为合法的操作。否则称这个操 作不合法,游戏不会处理这个操作。游戏的目的是消除尽量多的棋子。 给出这样一个游戏和一个人的玩法。
你需要:
1.指出此人能消去多少棋子。
2.给出一种能消去最多棋子的方案。

题解:给每行每列开一个set,然后模拟。

代码极致恶心,(不要看我的代码,超长)

犯得错误:
1.set迭代器到处都要判断是否到begin或end;
2.check颜色是否可以连接有两种情况:有拐弯,在同一行或列;
……

#include<cstdio>
#include<set>
#include<map>
#include<queue>
#include<algorithm>
using namespace std;
const int MAXN=100005;
int R,C,N;
struct Point
{
    int x,y;
    Point(){}
    Point(int _x,int _y):x(_x),y(_y){}
    void Read(){scanf("%d%d",&x,&y);}
    bool operator < (Point t)const
    {return x<t.x||(x==t.x&&y<t.y);}
}P[MAXN][2];
struct ID
{
    int pri,c,i;
    ID(){}
    ID(int _p,int _c,int _i):pri(_p),c(_c),i(_i){}
    bool operator < (ID t)const
    {return pri<t.pri;}
};
set<ID> row[MAXN],col[MAXN];
map<Point,bool> has;
void Read()
{
    scanf("%d%d",&R,&C);
    scanf("%d",&N);
    for(int i=1;i<=N;i++)
        P[i][0].Read(),P[i][1].Read();
}
void Init()
{
    for(int i=1;i<=R;i++)row[i].clear();
    for(int i=1;i<=C;i++)col[i].clear();
    has.clear();
    for(int i=1;i<=N;i++)
    {
        has[P[i][0]]=1;
        has[P[i][1]]=1;
        row[P[i][0].x].insert(ID(P[i][0].y,i,0));
        row[P[i][1].x].insert(ID(P[i][1].y,i,1));
        col[P[i][0].y].insert(ID(P[i][0].x,i,0));
        col[P[i][1].y].insert(ID(P[i][1].x,i,1));
    }
}
void erase(int color)
{
    row[P[color][0].x].erase(ID(P[color][0].y,color,0));
    row[P[color][1].x].erase(ID(P[color][1].y,color,1));
    col[P[color][0].y].erase(ID(P[color][0].x,color,0));
    col[P[color][1].y].erase(ID(P[color][1].x,color,1));
    has[P[color][0]]=0;
    has[P[color][1]]=0;
}
void solve1()
{
    int M;
    scanf("%d",&M);
    int x,y;
    char d1,d2;
    set<ID>::iterator it;
    int color=-1,ans=0;
    for(int i=1;i<=M;i++)
    {
        scanf("%d %d %c %c",&x,&y,&d1,&d2);
        if(has[Point(x,y)])
            continue;
        color=-1;
        if(d1=='U'||d2=='U')
        {
            it=col[y].lower_bound(ID(x,0,0));
            if(it==col[y].begin())continue;
            it--;
            if(~color&&it->c!=color)
                continue;
            else if(~color&&it->c==color)
            {
                erase(color);
                ans++;
                continue;
            }
            else if(color==-1)
                color=it->c;
        }
        if(d1=='D'||d2=='D')
        {
            it=col[y].upper_bound(ID(x,0,0));
            if(it==col[y].end())continue;
            if(~color&&it->c!=color)
                continue;
            else if(~color&&it->c==color)
            {
                erase(color);
                ans++;
                continue;
            }
            else if(color==-1)
                color=it->c;
        }
        if(d1=='L'||d2=='L')
        {
            it=row[x].lower_bound(ID(y,0,0));
            if(it==row[x].begin())continue;
            it--;
            if(~color&&it->c!=color)
                continue;
            else if(~color&&it->c==color)
            {
                erase(color);
                ans++;
                continue;
            }
            else if(color==-1)
                color=it->c;
        }
        if(d1=='R'||d2=='R')
        {
            it=row[x].upper_bound(ID(y,0,0));
            if(it==row[x].end())continue;
            if(~color&&it->c!=color)
                continue;
            else if(~color&&it->c==color)
            {
                erase(color);
                ans++;
                continue;
            } 
            else if(color==-1)
                color=it->c;
        }
    }
    printf("%d\n",ans);
}
queue<int>Q;
int output[MAXN][4],cnt;
bool check(int color)
{
    if(P[color][0].x==P[color][1].x&&(P[color][0].y==P[color][1].y-1||P[color][0].y==P[color][1].y+1))return 0;
    if(P[color][0].y==P[color][1].y&&(P[color][0].x==P[color][1].x-1||P[color][0].x==P[color][1].x+1))return 0;
    set<ID>::iterator it;
    bool flag=1;
    int x1=P[color][0].x,x2=P[color][1].x,y1=P[color][0].y,y2=P[color][1].y;
    if(x1==x2)
    {
        it=row[x1].find(ID(y1,color,0));
        if(y1<y2)
        {
            it++;
            if(it!=row[x1].end()&&it->c==color)
            {
                cnt++;
                output[cnt][0]=x1;output[cnt][1]=y1+1;
                output[cnt][2]='L';output[cnt][3]='R';
                return 1;
            }
        }
        if(y2<y1&&it!=row[x1].begin())
        {
            it--;
            if(it->c==color)
            {
                cnt++;
                output[cnt][0]=x1;output[cnt][1]=y1-1;
                output[cnt][2]='L';output[cnt][3]='R';
                return 1;
            }
        }
        return 0;
    }
    if(y1==y2)
    {
        it=col[y1].find(ID(x1,color,0));
        if(x1<x2)
        {
            it++;
            if(it!=col[y1].end()&&it->c==color)
            {
                cnt++;
                output[cnt][0]=x1+1;output[cnt][1]=y1;
                output[cnt][2]='U';output[cnt][3]='D';
                return 1;
            }
        }
        if(x2<x1&&it!=col[y1].begin())
        {
            it--;
            if(it->c==color)
            {
                cnt++;
                output[cnt][0]=x1-1;output[cnt][1]=y1;
                output[cnt][2]='U';output[cnt][3]='D';
                return 1;
            }
        }
        return 0;
    }
    it=row[x1].find(ID(y1,color,0));
    if(y1<y2)
    {
        it++;
        if(it!=row[x1].end()&&it->pri<=y2)
            flag=0;
    }
    else if(y2<y1)
    {
        if(it!=row[x1].begin())
        {
            it--;
            if(it->pri>=y2)
                flag=0;
        }
    }
    if(flag)
    {
        it=col[y2].find(ID(x2,color,1));
        if(x2<x1)
        {
            it++;
            if(it!=col[y2].end()&&it->pri<=x1)
                flag=0;
        }
        else if(x1<x2)
        {
            if(it!=col[y2].begin())
            {
                it--;
                if(it->pri>=x1)
                    flag=0;
            }
        }
    }
    if(flag)
    {
        cnt++;
        output[cnt][0]=x1;output[cnt][1]=y2;
        if(x1>x2)output[cnt][2]='U';
        else output[cnt][2]='D';
        if(y1>y2)output[cnt][3]='R';
        else output[cnt][3]='L';
        return 1;
    }
    flag=1;
    it=row[x2].find(ID(y2,color,1));
    if(y2<y1)
    {
        it++;
        if(it!=row[x2].end()&&it->pri<=y1)
            flag=0;
    }
    else if(y1<y2)
    {
        if(it!=row[x2].begin())
        {
            it--;
            if(it->pri>=y1)
                flag=0;
        }
    }
    if(flag)
    {
        it=col[y1].find(ID(x1,color,0));
        if(x1<x2)
        {
            it++;
            if(it!=col[y1].end()&&it->pri<=x2)
                flag=0;
        }
        else if(x2<x1)
        {
            if(it!=col[y1].begin())
            {
                it--;
                if(it->pri>=x2)
                    flag=0;
            }
        }
    }
    if(flag)
    {
        cnt++;
        output[cnt][0]=x2;output[cnt][1]=y1;
        if(x1<x2)output[cnt][2]='U';
        else output[cnt][2]='D';
        if(y1<y2)output[cnt][3]='R';
        else output[cnt][3]='L';
        return 1;
    }
    return 0;
}
int que[10],h;
void update(const Point &p,int color)
{
    set<ID>::iterator it,tt;
    it=row[p.x].find(ID(p.y,color,0));
    tt=it;
    if(tt!=row[p.x].begin())
    {
        tt--;
        que[++h]=tt->c;
    }
    tt=it;
    tt++;
    if(tt!=row[p.x].end())
        que[++h]=tt->c;
    it=col[p.y].find(ID(p.x,color,0));
    tt=it;
    if(tt!=col[p.y].begin())
    {
        tt--;
        que[++h]=tt->c;
    }
    tt=it;
    tt++;
    if(tt!=col[p.y].end())
        que[++h]=tt->c;
}
bool vis[MAXN];
void solve2()
{
    for(int i=1;i<=N;i++)
        if(check(i))
        {
            Q.push(i);
            vis[i]=1;
        }
    while(!Q.empty())
    {
        int t=Q.front();
        Q.pop();
        h=0;
        update(P[t][0],t);
        update(P[t][1],t);
        sort(que+1,que+h+1);
        h=unique(que+1,que+h+1)-que-1;
        erase(t);
        for(int i=1;i<=h;i++)
            if(!vis[que[i]]&&check(que[i]))
            {
                Q.push(que[i]);
                vis[que[i]]=1;
            }
    }
    printf("%d\n",cnt);
    for(int i=1;i<=cnt;i++)
        printf("%d %d %c %c\n",output[i][0],output[i][1],output[i][2],output[i][3]);
}
int main()
{
    Read();
    Init();
    solve1();
    Init();
    solve2();
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值