NOIP2011【Mayan游戏】

来源:互联网 发布:其恕乎的其是什么意思 编辑:程序博客网 时间:2024/04/27 21:14



【题解】

   一题比较玄学的搜索,虽然我一直不明白为什么不会T但正解就是这个

   首先很容易想到用右移(1)代替左移(-1)保证字典序(若当前这格是空格才是左移)

   每次搜索一步就做清理(clear)注意一定要多次清理直到无法清理为止,由于矩阵比较小(5*7)所以掉落了清理的步骤就随便做一下(参考程序中clear)(打这个的时候把变量打错了调了一个小时,汗)

   最后走了走了n步后判断有没有全被清完就好了

   一个小优化,每次搜索前,判断有没有一种颜色数量小于三,有的话跳出

  详见代码

  

#include <algorithm>#include <iostream>#include <cstdlib>#include <cstring>#include <string>#include <cstdio>#include <queue>#include <ctime>#include <cmath>using namespace std;int i,j,k,m,n;int a[10][10],num[10],c[10][10];struct info  {  int x,y,d;  }ans[10];bool empty()  {  for (int i=0;i<5;i++) if (a[i][0]!=0) return 0;return 1;   }bool clear()  {  int i,j,k,l,pd=0,x,y,o;  memset(c,0,sizeof c);  for (i=0;i<5;i++)    for (j=l=0;j<7;j++) if (a[i][j]) c[i][l++]=a[i][j];  if (ans[1].x==2&&ans[2].x==1&&ans[3].x==2&&ans[1].y==0&&ans[2].y==1&&ans[3].y==4&&ans[1].d==0&&ans[2].d==0&&ans[3].d==1)    {      k=0; }   for (i=0;i<3;i++)    for (j=0;j<7;j++)      if (c[i][j])  {      for (x=i+1;x<5&&c[x][j]==c[i][j];x++);x--;      if (x-i+1>=3)         {for (k=i;k<=x;k++)  {  for (l=j;l>=0&&c[k][l]==c[k][j];)    l--;  l++;  for (y=j;y<7 &&c[k][y]==c[k][j];)  y++;  y--;  if (y-l+1>=3) for (o=l;o<=y;o++) c[k][o]=0;  else c[k][j]=0;  }pd=1;  }  }    for (i=0;i<5;i++)    for (j=0;j<5;j++)      if (c[i][j])  {      for (y=j+1;y<7&&c[i][y]==c[i][j];y++);y--;      if (y-j+1>=3)         {for (o=j;o<=y;o++)  {  for (l=i;l>=0&&c[l][o]==c[i][o];l--);l++;  for (x=i;x<5 &&c[x][o]==c[i][o];x++);x--;  if (x-l+1>=3) for (k=l;k<=x;k++) c[k][o]=0;  else c[i][o]=0;  }pd=1;  }  }memcpy(a,c,sizeof a);return pd;  }void dfs(int k)  {  int i,j;  if (k>n)    {    if (empty())      {      for (int i=1;i<=n;i++)        if (ans[i].d) printf("%d %d -1\n",ans[i].x+1,ans[i].y);        else printf("%d %d 1\n",ans[i].x,ans[i].y);      exit(0);  }    return;  }memset(num,0,sizeof(num));for (i=0;i<5;i++) for (j=0;j<7;j++) num[a[i][j]]++;for (i=1;i<=10;i++) if (num[i]<=2&&num[i]>=1) return;    for (i=0;i<4;i++)      for (j=0;j<7;j++)        if (a[i+1][j]!=a[i][j])  {  int b[10][10];  memcpy(b,a,sizeof(b));        ans[k]=(info){i,j,!a[i][j]};        swap(a[i+1][j],a[i][j]);        for (;clear(););        dfs(k+1);        memcpy(a,b,sizeof(a));  }  }int main()  {  scanf("%d",&n);  for (i=0;i<5;i++)   for (j=0;;j++)   {    scanf("%d",&a[i][j]);    if (!a[i][j]) break;  }dfs(1);printf("-1");    }

  

0 0
原创粉丝点击