[BZOJ3519][Zjoi2014][模拟]消棋子

这篇博客主要介绍了如何解决BZOJ3519题目的消棋子问题,重点在于使用模拟方法。作者提到在解决过程中首次尝试使用set数据结构,并体会到set在处理此类问题时的便利性。对于第一部分的模拟询问,通过set记录棋盘状态,简化操作。第二部分的策略是采用贪心算法,每次都消除可消除的棋子。尽管代码较长且思路可能不清晰,但这种方法能够运行。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

巨烦的模拟。
差不多算是第一次用set,发现set是个好东西。

对于第一个询问,用set记录每行每列放棋子的情况,那么对于这个人的每次操作,直接在set上模拟就好了
第二问贪心,每次把能消掉的棋子消掉就可以了。

代码长,思路乱,还跑得慢……

#include <cstdio>
#include <iostream>
#include <algorithm>
#include <set>
#define N 100010
#define pc(a) putchar(a)

using namespace std;

typedef pair<int,int> prs;
typedef set<prs>::iterator it;
typedef pair<it,it> prt;

set<prs> r[N],l[N],r1[N],l1[N];
prs A[N],B[N],Ans1[N],Ans2[N];
int n,R,C,x1,x2,y1,y2,m,V[N],Acnt;
char op1,op2,pt[5]={' ','R','L','U','D'};

void dfs(int);

void del(int k){
    V[k]=1;
    it x=l[A[k].first].find(prs(A[k].second,k)),x1,x2,x3,x4;
    x1=--x;++x;x2=++x;--x;
    l[A[k].first].erase(x);

    x=l[B[k].first].find(prs(B[k].second,k));
    x3=--x;++x;x4=++x;--x;
    l[B[k].first].erase(x);

    it y=r[A[k].second].find(prs(A[k].first,k)),y1,y2,y3,y4;
    y1=--y;++y;y2=++y;--y;
    r[A[k].second].erase(y);

    y=r[B[k].second].find(prs(B[k].first,k));
    y3=--y;++y;y4=++y;--y;
    r[B[k].second].erase(y);
    //printf("%d %d %d %d %d %d %d %d\n",x1->second,x2->second,x3->second,x4->second,y1->second,y2->second,y3->second,y4->second);
    if(x1->second>0) dfs(x1->second);
    if(x2->second>0) dfs(x2->second);

    if(x3->second>0) dfs(x3->second);
    if(x4->second>0) dfs(x4->second);

    if(y1->second>0) dfs(y1->second);
    if(y2->second>0) dfs(y2->second);

    if(y3->second>0) dfs(y3->second);
    if(y4->second>0) dfs(y4->second);
}

void print(int x,int y,int a,int b){
    ++Acnt;
    Ans1[Acnt]=prs(x,y);
    Ans2[Acnt]=prs(a,b);
}

void dfs(int k){
    if(V[k]) return;
    if(A[k].first==B[k].first){
        if(A[k].second>B[k].second){
            it x=l[A[k].first].find(prs(B[k].second,k)),y=l[A[k].first].find(prs(A[k].second,k));
            if((++x,x--==y)&&x->first+1<y->first){
                print(A[k].first,A[k].second-1,1,2);
                del(k);
                return;
            }
        }
        else{
            it x=l[A[k].first].find(prs(B[k].second,k)),y=l[A[k].first].find(prs(A[k].second,k));
            if((--x,x++==y)&&x->first-1>y->first){
                print(A[k].first,A[k].second+1,1,2);
                del(k);
                return;
            }
        }
        return;
    }
    if(A[k].second==B[k].second){
        if(A[k].first>B[k].first){
            it x=r[A[k].second].find(prs(B[k].first,k)),y=r[A[k].second].find(prs(A[k].first,k));
            if((++x,x--==y)&&x->first+1<y->first){
                print(A[k].first-1,A[k].second,3,4);
                del(k);
                return;
            }
        }
        else{
            it x=r[A[k].second].find(prs(B[k].first,k)),y=r[A[k].second].find(prs(A[k].first,k));
            if((--x,x++==y)&&x->first-1>y->first){
                print(A[k].first+1,A[k].second,3,4);
                del(k);
                return;
            }
        }
        return;
    }
    it x=l[A[k].first].lower_bound(prs(B[k].second,0));
    if((x->first!=B[k].second)&&(x->second==k||(--x,(x++)->second==k))){
        it y=r[B[k].second].lower_bound(prs(A[k].first,0));
        if(y->second==k||(--y,(y++)->second==k)){
            int a,b;
            if(A[k].first<B[k].first) a=4;else a=3;
            if(B[k].second>A[k].second) b=2;else b=1;
            print(A[k].first,B[k].second,a,b);
            del(k);
            return;
        }
    }
    x=l[B[k].first].lower_bound(prs(A[k].second,0));
    if(x->first!=A[k].second&&(x->second==k||(--x,(x++)->second==k))){
        it y=r[A[k].second].lower_bound(prs(B[k].first,0));
        if(y->second==k||(--y,(y++)->second==k)){
            int a,b;
            if(A[k].first>B[k].first) a=4; else a=3;
            if(B[k].second>A[k].second) b=1; else b=2;
            print(B[k].first,A[k].second,a,b);
            del(k);
            return;
        }
    }
}

inline char gc(){
    static char buf[100000],*p1=buf,*p2=buf;
    if(p1==p2){
        p2=(p1=buf)+fread(buf,1,100000,stdin);
        if(p1==p2) return EOF;
    }
    return *p1++;
}

inline void reaD(int &x){
    char Ch=gc();x=0;
    for(;Ch>'9'||Ch<'0';Ch=gc());
    for(;Ch>='0'&&Ch<='9';x=x*10+Ch-'0',Ch=gc());
}

int w[30],wt;

inline void Pt(int x){
    if(!x){pc(48);return;}
    while(x) w[++wt]=x%10,x/=10;
    for(;wt;wt--)pc(w[wt]+48);
}

int main(){
    freopen("eliminate.in","r",stdin);
    freopen("eliminate.out","w",stdout);
    reaD(R);reaD(C);reaD(n);
    for(int i=1;i<=R;i++) l[i].insert(prs(0,0)),l[i].insert(prs(C+1,0)),l1[i].insert(prs(0,0)),l1[i].insert(prs(C+1,0));
    for(int i=1;i<=C;i++) r[i].insert(prs(0,0)),r[i].insert(prs(R+1,0)),r1[i].insert(prs(0,0)),r1[i].insert(prs(R+1,0));
    for(int i=1;i<=n;i++){
        reaD(x1);reaD(y1);reaD(x2);reaD(y2);
        A[i]=prs(x1,y1);B[i]=prs(x2,y2);
        l[x1].insert(prs(y1,i));l[x2].insert(prs(y2,i));
        r[y1].insert(prs(x1,i));r[y2].insert(prs(x2,i));
        l1[x1].insert(prs(y1,i));l1[x2].insert(prs(y2,i));
        r1[y1].insert(prs(x1,i));r1[y2].insert(prs(x2,i));
    }
    reaD(m);
    int cnt=0;
    for(int i=1,a,b;i<=m;i++){
        reaD(a);reaD(b);
        while((op1=gc())!='L'&&op1!='R'&&op1!='U'&&op1!='D');
        while((op2=gc())!='L'&&op2!='R'&&op2!='U'&&op2!='D');
        it x=l1[a].lower_bound(prs(b,0)),y=r1[b].lower_bound(prs(a,0));
        if(x->first==b||y->first==a) continue;
        if(op1=='L') a=(--x)->second,++x; else
        if(op1=='R') a=x->second; else
        if(op1=='U') a=(--y)->second,++y; else
        a=y->second;
        if(op2=='L') b=(--x)->second,++x; else
        if(op2=='R') b=x->second; else
        if(op2=='U') b=(--y)->second,++y; else
        b=y->second;
        if(a==b&&a&&b) cnt++;else continue;
        l1[A[a].first].erase(l1[A[a].first].find(prs(A[a].second,a)));
        l1[B[a].first].erase(l1[B[a].first].find(prs(B[a].second,a)));
        r1[A[a].second].erase(r1[A[a].second].find(prs(A[a].first,a)));
        r1[B[a].second].erase(r1[B[a].second].find(prs(B[a].first,a)));
    }
    Pt(cnt);pc('\n');
    for(int i=1;i<=n;i++)
        if(!V[i])dfs(i);
    Pt(Acnt);pc('\n');
    for(int i=1;i<=Acnt;i++) Pt(Ans1[i].first),pc(' '),Pt(Ans1[i].second),pc(' '),pc(pt[Ans2[i].first]),pc(' '),pc(pt[Ans2[i].second]),pc('\n');
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值