【题解】
一题比较玄学的搜索,虽然我一直不明白为什么不会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");
}