1. 程式人生 > >UESTC 1951 LargeDumpling與1/N線段樹

UESTC 1951 LargeDumpling與1/N線段樹

nbsp while 一個 front lin namespace tar coj iostream

題目:http://www.qscoj.cn/#/problem/show/1951

逆向思考,先全部種上再一個一個刪除

先把最外圍都標記成空地,再bfs將所有的空地標記

剩下的不是空地也不是樹的就是答案

刪除的時候只有3種情況

1.周圍都是空地 直接變成空地

2.周圍沒有空地 答案+1 變成答案區間

3.既有空地也有樹 把連通塊都變成空地

#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<cmath>
#include<algorithm>
#include<vector>
#include<queue>
#include<stack>
#include<map>
#include<set>
using namespace std;
const int N=1e5+5;
const int M=2e3+5;
int x[N],y[N],a[M][M],ans[N],s;
bool use[M][M];
int fx[4]={0,0,-1,1};
int fy[4]={1,-1,0,0};
struct p
{
    int x,y;
    p(int xx,int yy)
    {
        x=xx;
        y=yy;
    }
};
void bfs()
{
    memset(use,0,sizeof(use));
    queue<p> que;
    use[0][0]=1;
    que.push(p(0,0));
    while(!que.empty())
    {
        p t=que.front();
        que.pop();
        for(int i=0;i<4;i++)
        {
            int tx=t.x+fx[i],ty=t.y+fy[i];
            if (tx>=0&&tx<=2000&&ty>=0&&ty<=2000&&!use[tx][ty])
                if (a[tx][ty]!=1)
            {
                a[tx][ty]=2;
                que.push(p(tx,ty));
                use[tx][ty]=1;
            }
        }
    }
}
int check(int xx,int yy)
{
    if (a[xx-1][yy]==2&&a[xx+1][yy]==2&&a[xx][yy+1]==2&&a[xx][yy-1]==2) return 1;
    if (a[xx-1][yy]!=2&&a[xx+1][yy]!=2&&a[xx][yy+1]!=2&&a[xx][yy-1]!=2) return 2;
    return 3;
}
void bfs1(int xx,int yy)
{
    queue<p> que;
    que.push(p(xx,yy));
    while(!que.empty())
    {
        p t=que.front();
        que.pop();
        for(int i=0;i<4;i++)
        {
            int tx=t.x+fx[i],ty=t.y+fy[i];
            if (tx>=0&&tx<=2000&&ty>=0&&ty<=2000&&a[tx][ty]==0)
            {
                a[tx][ty]=2;
                s--;
                que.push(p(tx,ty));
            }
        }
    }
}
int main()
{
    int n;
    memset(a,0,sizeof(a));
    scanf("%d",&n);
    for(int i=1;i<=n;i++)
    {
        scanf("%d%d",&x[i],&y[i]);
        x[i]+=1000;y[i]+=1000;
        a[x[i]][y[i]]=1;
    }
    for(int i=0;i<=2000;i++)
    {
        a[0][i]=2;
        a[i][0]=2;
        a[i][2000]=2;
        a[2000][i]=2;
    }
    bfs();
    int tot=0;
    s=0;
    for(int i=0;i<=2000;i++)
        for(int j=0;j<=2000;j++)
            if (a[i][j]==0) s++;
    ans[++tot]=s;
    for(int i=n;i>1;i--)
    {
        int t=check(x[i],y[i]);
        if (t==1)
            a[x[i]][y[i]]=2;
        else if (t==2)
        {
            a[x[i]][y[i]]=0;
            s++;
        }
        else
        {
            a[x[i]][y[i]]=2;
            bfs1(x[i],y[i]);
        }
        ans[++tot]=s;
    }
    for(int i=tot;i>=1;i--)
        printf("%d\n",ans[i]);
    return 0;
}

  

UESTC 1951 LargeDumpling與1/N線段樹