JZOJ4389. 【GDOI2016模拟3.15】圈地游戏

这里写图片描述
这里写图片描述

题解

题目已经告诉了如何判断一个点是否在一个多边形里面,
而关于自交的问题,就将它当作没有自交就好了。

看到数据范围,特殊点只有很少,考虑如何设状态,
用fx,y,sfx,y,s表示当前走的点(x,y),特殊格子上面经过的线的奇偶性的2进制状态,
有了这个状态就可以bfs了。

code

#include <queue>
#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cstring>
#include <string.h>
#include <cmath>
#include <math.h>
#include <time.h>
#define ll long long
#define N 2560
#define M 103
#define db double
#define P putchar
#define G getchar
using namespace std;
char ch;
int f[23][23][1030],n,m,x,y,xx,yy,t,v,ss,sx,sy,tr;
int z[13],fx[4][2]={{-1,0},{0,-1},{1,0},{0,1}};
int head,tail,q[3][N*8],ans,p[2][13],cnt,w[13];
bool bz[23][23][1030];
char s[23][23];

int get(int x,int y,int s)
{
    for(int i=1;i<=cnt;i++)
        if(p[1][i]==y && p[0][i]>x)s^=z[i-1];
    return s;
}

void dfs(int ss,int x,int y)
{
    ans=max(ans,y-f[sx][sy][ss]);
    if(x>cnt)return;
    if('1'<=s[p[0][x]][p[1][x]] && s[p[0][x]][p[1][x]]<='8')
        dfs(ss|z[x-1],x+1,y+w[s[p[0][x]][p[1][x]]-'0']);
    dfs(ss,x+1,y);
}

int main()
{   
    z[0]=1;
    for(int i=1;i<12;i++)
        z[i]=z[i-1]<<1;

    scanf("%d%d",&n,&m);

    for(int i=1;i<=n;i++)
    {
        for(ch=G();!(ch=='#' || ch=='S' || ch=='.' || ch=='B' || ('1'<=ch && ch<='8'));ch=G());
        for(m=0;ch=='#' || ch=='S' || ch=='.' || ch=='B' || ('1'<=ch && ch<='8');ch=G())
        {
            s[i][++m]=ch;
            if(ch=='B' || ('1'<=ch && ch<='8'))
            {
                cnt++,p[0][cnt]=i,p[1][cnt]=m;
                if('1'<=ch && ch<='8')tr++;
            }
            if(ch=='S')sx=i,sy=m,s[i][m]='.';
        } 
    }

    for(int i=1;i<=tr;i++)
        scanf("%d\n",&w[i]);

    memset(f,127,sizeof(f));
    memset(bz,1,sizeof(bz));
    q[0][1]=sx;q[1][1]=sy;q[2][1]=0;//get(sx,sy,0);
    f[sx][sy][q[2][1]]=0;bz[sx][sy][q[2][1]]=0;
    for(head=0,tail=1;head<tail;)
    {
        head++;
        x=q[0][head];
        y=q[1][head];
        t=q[2][head];
        v=f[x][y][t];

        for(int k=0;k<4;k++)
        {
            xx=x+fx[k][0];
            yy=y+fx[k][1];
            ss=t;
            if(xx<1 || yy<1 || xx>n || yy>m)continue;
            if(s[xx][yy]!='.')continue;
            if(k==1)ss=get(x,yy,ss);
            if(k==3)ss=get(x,y,ss);

            if(f[xx][yy][ss]>v+1)
            {
                f[xx][yy][ss]=v+1;
                if(bz[xx][yy][ss])
                {
                    bz[xx][yy][ss]=0;
                    tail++;
                    q[0][tail]=xx;
                    q[1][tail]=yy;
                    q[2][tail]=ss;
                }
            }
        }
        bz[x][y][t]=1;
    }

    ans=-2147483647;
    dfs(0,1,0);
    printf("%d\n",ans);

    return 0;
}

猜你喜欢

转载自blog.csdn.net/lijf2001/article/details/81134950