zoukankan      html  css  js  c++  java
  • bzoj2719[Violet 4]银河之星

    Description

     

    Input

    Output



    一道坑爹的搜索……题意是可以往任意方向移动3格,或者如果旁边有格子的时候可以越过它移动,然后把它吃掉。要求吃到最后一个的位置在x0,y0

    注意到可以越三格移动……所以取棋盘左上的3*3的格子,可以证明无论棋盘上何处的格子都可以通过一次3格的移动走到3*3的格子里

    然后就可以用一个3*3的数组保存棋盘的状态,然后因为总的格子数小,还可以用10^9的数保存棋盘的状态(注意要算出3*3的九宫格中每一格最多放多少个,不然会wa)

    然后就可以dfs搞之

    再加个记忆化更快(注意每组数据都要重新hash)

    #include<cstdio>
    #include<cstring>
    #define mod 1000007
    const int mx[8]={0,0,-1,1,-1,1,-1,1};
    const int my[8]={1,-1,0,0,1,-1,-1,1};
    struct hashing{
    	int test,next;
    	bool ok;
    }hash[1000010];
    int head[mod];
    int cnt,tox,toy;
    int maxnum[4][4];
    int a[4][4];
    int K,N,M;
    inline int find(int now)
    {
    	int s=now%mod;
    	for (int i=head[s];i;i=hash[i].next)
    	  if (hash[i].test==now)return hash[i].ok;
    	return -1;
    }
    inline void ins(int now,bool ok)
    {
    	int s=now%mod;
    	hash[++cnt].test=now;
    	hash[cnt].ok=ok;
    	hash[cnt].next=head[s];
    	head[s]=cnt;
    }
    inline bool ok()
    {
    	for(int i=1;i<=9;i++)
    	{
    		int ny=i%3;if (!ny)ny=3;int nx=(i-1)/3+1;
    		if (nx==tox&&ny==toy&&a[nx][ny]!=1)return 0;
    		if (nx!=tox||ny!=toy)if(a[nx][ny]!=0)return 0;
    	}
    	return 1;
    }
    inline bool dfs()
    {
    	int now=0;
    	for (int i=1;i<=3;i++)
    	  for(int j=1;j<=3;j++)
    	    now=now*10+a[i][j];
    	int fnd=find(now);if (fnd!=-1)return fnd;
    	for (int i=1;i<=3;i++)
    	  for (int j=1;j<=3;j++)
    	    if(a[i][j])
    	    {
    	    	for(int k=0;k<8;k++)
    	    	{
    	    		bool mrx=0,mry=0;
    	    		int sx=i+mx[k];if (sx>3){sx-=3;mrx=1;}if (sx<1){sx+=3;mrx=1;}
    	    		int sy=j+my[k];if (sy>3){sy-=3;mry=1;}if (sy<1){sy+=3;mry=1;}
    	    		if (!a[sx][sy])continue;
    	    		if ((mrx||mry)&&a[i][j]==maxnum[i][j])continue;
    	    		int tx=i+2*mx[k];if (tx>3)tx-=3;if (tx<1)tx+=3;
    	    		int ty=j+2*my[k];if (ty>3)ty-=3;if (ty<1)ty+=3;
    	    		if (a[tx][ty]==maxnum[tx][ty])continue;
    	    		a[i][j]--;
    	    		a[sx][sy]--;
    	    		a[tx][ty]++;
    	    		if (dfs())
    	    		{
    	    			ins(now,1);
    	    			return 1;
    	    		}
    	    		a[i][j]++;
    	    		a[sx][sy]++;
    	    		a[tx][ty]--;
    	    	}
    	    }
    	ins(now,0);
    	return 0;
    }
    int main()
    {
    	freopen("galaxy.in","r",stdin);
    	freopen("galaxy.out","w",stdout);
    	while (scanf("%d%d%d%d%d",&K,&N,&M,&tox,&toy)!=EOF)
    	  {
    	  	memset(hash,0,sizeof(hash));
    	  	memset(head,0,sizeof(head));
    	  	memset(a,0,sizeof(a));
    	  	cnt=0;
    	  	tox=(tox-1)%3+1;
    	  	toy=(toy-1)%3+1;
    	  	int now=0;
    	  	for (int i=1;i<=9;i++)
    	  	{
    	  		int xx=(i-1)/3+1;
    	  		int yy=(i-1)%3+1;
    	  		now*=10;
    	  		if (xx==tox&&yy==toy)now++;
    	  	}
    	  	ins(now,1);
    	  	for(int i=1;i<=3;i++)
    		for(int j=1;j<=3;j++)
    		maxnum[i][j]=(N/3)*(M/3)+(N%3>=i)*(M/3)+(M%3>=j)*(N/3)+(N%3>=i&&M%3>=j);
    	  	for (int i=1;i<=K;i++)
    	  	  {
    	  	  	int x,y;
    	  	  	scanf("%d%d",&x,&y);
    	  	  	x=(x-1)%3+1;
    	  	  	y=(y-1)%3+1;
    	  	  	a[x][y]++;
    	  	  }
    	  	bool mrkres=0;
    	  	for (int i=1;i<=3;i++)
    	  	  for (int j=1;j<=3;j++)
    	  	    if (a[i][j]>maxnum[i][j])mrkres=1;
    		if (mrkres)
    		{
    		  printf("No
    ");
    		  continue;
    		}
    		if (dfs())printf("Yes
    ");
    		else printf("No
    ");
    	  }
    }
    

      

    ——by zhber,转载请注明来源
  • 相关阅读:
    vsftp 虚拟用户测试
    RHEL7 MariaDB测试
    安装xenapp后,非管理员连接RDP出现桌面当前不可用的解决方法
    sqrt函数的实现
    O2O、C2C、B2B、B2C
    libsvm使用说明
    如何确定最适合数据集的机器学习算法
    知乎日报:她把全世界的学术期刊都黑了
    逻辑回归应用之Kaggle泰坦尼克之灾
    非均衡数据分布的分类问题
  • 原文地址:https://www.cnblogs.com/zhber/p/4036000.html
Copyright © 2011-2022 走看看