传送门:https://www.luogu.org/problemnew/show/P1312
辣鸡模拟题!就是暴力乱搞,然后一堆小细节要注意qwq
把某谷的数据点骗完了终于过了呕
然后是剪枝的四个原则:(转载)
(1)交换两个颜色相同的块没有意义
(2)一个块的左边是非空块时不需要考虑左移,因为会和之前的块右移重复,即只有当左块为空时才左移
(3)根据题目优先度的排序,可以知道,右移优先于左移,所以在dfs时先考虑右移
(4)如果有一种颜色当前的块数目x满足1<=x<=2,则此情况不合法
然后细心打一下就好啦....
#include <iostream>
#include <algorithm>
#include <cstring>
#include <cstdlib>
#include <cstdio>
#include <cmath>
#include <ctime>
#define maxn 15
using namespace std;
bool flag,tag[maxn][maxn];
int n,a[maxn][maxn],cnt[maxn+5],ans[maxn][3];
int read()
{
int xx=0,kk=1;char ch=' ';
while(!isdigit(ch)){ch=getchar();if(ch=='-')kk=-1;}
while(isdigit(ch)){xx=xx*10+ch-'0';ch=getchar();}
return kk*xx;
}
bool find()
{
bool flag=false;
memset(tag,false,sizeof(tag));
for(int i=1;i<=5;++i)
for(int j=1;j<=7;++j)
{
if(!a[i][j]) continue;
if(a[i][j]==a[i-1][j]&&a[i][j]==a[i+1][j])
tag[i][j]=tag[i-1][j]=tag[i+1][j]=true,flag=true;
if(a[i][j]==a[i][j-1]&&a[i][j]==a[i][j+1])
tag[i][j]=tag[i][j-1]=tag[i][j+1]=true,flag=true;
}
return flag;
}
void del()
{
for(int i=1;i<=5;++i)
{
int low=0,sum=0;
for(int j=1;j<=7;++j)
{
if(!low&&tag[i][j]) low=j;
if(tag[i][j]) sum++;
}
for(int j=1;j<=7;++j)
if(j>=low) a[i][j]=a[i][j+sum];
}
}
bool success()
{
for(int i=1;i<=5;++i)
for(int j=1;j<=7;++j)
if(a[i][j]) return false;
return true;
}
bool check()
{
memset(cnt,0,sizeof(cnt));
for(int i=1;i<=5;++i)
for(int j=1;j<=7;++j)
if(a[i][j]) cnt[a[i][j]]++;
for(int i=1;i<=10;++i)
if(cnt[i]&&cnt[i]<3) return false;
return true;
}
bool dfs(int x,int y,int dep,int dir)
{
if(dep<0||x+dir<1||x+dir>5) return false;
if(a[x+dir][y]==a[x][y]) return false;
if(dir==-1&&a[x+dir][y]) return false;
if(!check()) return false;
int tmp[maxn][maxn],len=0;
while(!a[x+dir][y-len]&&len<y) len++;
if(len)
{
swap(a[x][y],a[x+dir][y-len+1]);
for(int i=y;i<=7;++i) a[x][i]=a[x][i+1];
}
else swap(a[x][y],a[x+dir][y]);
while(find()) del();
memcpy(tmp,a,sizeof(tmp));
if(success())
{
flag=true;
ans[dep][0]=x,ans[dep][1]=y,ans[dep][2]=dir;
return true;
}
for(int i=1;i<=5;++i)
for(int j=1;j<=7;++j)
{
if(!a[i][j]) continue;
memcpy(a,tmp,sizeof(a));
if(dfs(i,j,dep-1,1))
{
ans[dep][0]=x,ans[dep][1]=y,ans[dep][2]=dir;
return true;
}
memcpy(a,tmp,sizeof(a));
if(dfs(i,j,dep-1,-1))
{
ans[dep][0]=x,ans[dep][1]=y,ans[dep][2]=dir;
return true;
}
memcpy(a,tmp,sizeof(a));
}
return false;
}
int main()
{
n=read();
int tmp[maxn][maxn];
for(int i=1;i<=5;++i)
for(int j=1;j<=8;++j)
{
a[i][j]=read();
if(!a[i][j]) break;
}
memcpy(tmp,a,sizeof(a));
for(int i=1;i<=5;++i)
for(int j=1;j<=7;++j)
{
if(!a[i][j]) continue;
memcpy(a,tmp,sizeof(tmp));
if(dfs(i,j,n-1,1)) break;
memcpy(a,tmp,sizeof(tmp));
if(dfs(i,j,n-1,-1)) break;
}
if(flag)
{
for(int i=n-1;i>=0;--i)
if(ans[i][0]&&ans[i][1]) printf("%d %d %d\n",ans[i][0]-1,ans[i][1]-1,ans[i][2]);
}
else puts("-1");
return 0;
}