题目:https://www.luogu.org/problemnew/show/P1312
思路:
如果当前点与其右边点同色(或都不存在),则剪枝进行优化。
如果当前点有方块,则向左移,如果当前点没有方块,则其右边方块往左移。
所以只需要关注第0-4列的点,共计28个状态。
交换两个点后,再让方块掉落,掉落后再消除方块,如果又可以有方块掉落,则再掉落,然后可以消除,则再消除,直到不能消除为止——从而交换两个点后,应该采用循环来处理掉落与消除。
回溯,应该回溯到交换两个点之前的状态。可以用memcpy函数,节省代码量。
说到底,本题不难,关键在于处理好全局变量、局部变量,码之时要仔细,不要把i写成j,或者弄错横、纵坐标,更关键的是,码之前手工模拟清楚。
本题还可以再优化,比如某种颜色最后剩下块数少于3块,肯定消除不完,
AC代码:
#include<cstdio>
#include<iostream>
#include<cstring>
#include<cstdlib>
using namespace std;
int n,map[6][8],vis[6][8];
int x[6],y[6],g[6];
void tmpprint(){
for(int j=6;j>=0;j--){
for(int i=0;i<=4;i++)
if(map[i][j])cout<<map[i][j];
else cout<<' ';
cout<<"\n";
}
}
void diaoluo(){
for(int i=0;i<=4;i++){
for(int j=0;j<=5;j++){
if(map[i][j])continue;
for(int k=j+1;k<=6;k++){
if(map[i][k]==0)continue;
map[i][j]=map[i][k];
map[i][k]=0;
break;//important!!!
}
}
}
}
bool xiaochu(){
bool flg=0;
for(int i=0;i<=4;i++)
for(int j=0;j<=4;j++)
if(map[i][j]==map[i][j+1]
&& map[i][j]==map[i][j+2]
&& map[i][j]){
vis[i][j]=vis[i][j+1]=vis[i][j+2]=1;
flg=1;
}
for(int j=0;j<=6;j++)
for(int i=0;i<=2;i++)
if(map[i][j]==map[i+1][j]
&& map[i][j]==map[i+2][j]
&& map[i][j]){
vis[i][j]=vis[i+1][j]=vis[i+2][j]=1;
flg=1;
}
for(int i=0;i<=4;i++)
for(int j=0;j<=6;j++)
if(vis[i][j]==1){
map[i][j]=0;
vis[i][j]=0;
}
if(flg){
return 1;
}
else return 0;
}
bool judge(){
for(int i=0;i<=4;i++)
for(int j=0;j<=6;j++)
if(map[i][j])return 0;
return 1;
}
void dfs(int stp){
if(stp>n){
if(judge()){
for(int i=1;i<=n;i++)
printf("%d %d %d\n",x[i],y[i],g[i]);
exit(0);
}
return;
}
for(int i=0;i<=3;i++)
for(int j=0;j<=6;j++)
if(map[i][j]!=map[i+1][j]){//剪枝优化
//写成map[i][j]==map[i][j+1]检查用时1个小时!!!
if(map[i][j]==0)x[stp]=i+1,y[stp]=j,g[stp]=-1;//记录
else x[stp]=i,y[stp]=j,g[stp]=1;
int tmpmap[6][8];//局部变量。important!!!
memcpy(tmpmap,map,sizeof(tmpmap));
swap(map[i][j],map[i+1][j]);
diaoluo();
while(xiaochu())diaoluo();
//写成while(xiaochu())diaoluo;
//检查用时1个小时!!!
dfs(stp+1);
memcpy(map,tmpmap,sizeof(map));//回溯
}
}
int main(){
// freopen("in.txt","r",stdin);
cin>>n;
for(int i=0;i<=4;i++){
int x,j=0;
while(scanf("%d",&x)&&x) map[i][j++]=x;
}//i列,j行
dfs(1);
printf("-1\n");
return 0;
}