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,转载请注明来源
  • 相关阅读:
    Elementary Methods in Number Theory Exercise 1.2.25
    Elementary Methods in Number Theory Exercise 1.2.14
    图解欧几里德算法
    图解欧几里德算法
    Elementary Methods in Number Theory Exercise 1.2.14
    Android中的长度单位详解(dp、sp、px、in、pt、mm)
    分享下多年积累的对JAVA程序员成长之路的总结
    android异常之都是deamon惹的祸The connection to adb is down, and a severe error has occured.
    TomatoCartv1.1.8.2部署时报错
    JavaScript浏览器对象之二Document对象
  • 原文地址:https://www.cnblogs.com/zhber/p/4036000.html
Copyright © 2011-2022 走看看