UESTC 1951 LargeDumpling与1/N线段树

题目: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
",ans[i]);
    return 0;
}

  

原文地址:https://www.cnblogs.com/bk-201/p/9314610.html