社区讨论
萌新刚学 OI WA 全部 -1 求助
P1312[NOIP 2011 提高组] Mayan 游戏参与者 4已保存回复 3
讨论操作
快速查看讨论及其快照的属性,并进行相关操作。
- 当前回复
- 3 条
- 当前快照
- 1 份
- 快照标识符
- @lo99hi3c
- 此快照首次捕获于
- 2023/10/28 07:45 2 年前
- 此快照最后确认于
- 2023/10/28 07:45 2 年前
CPP
#include<bits/stdc++.h>
using namespace std;
int n,a[10][10],b[10][10];
bool p;
struct node{
int x,y,g;
bool operator <(const node &t) const{
if(x!=t.x)
return x<t.x;
if(y!=t.y)
return y<t.y;
return g>t.g;
}//比较
};//答案的结构体
vector<node> v1,v2;//存储答案
inline bool check(){
for(int i=0;i<5;++i)
for(int j=0;j<7;++j)
if(a[i][j])
return 0;
return 1;
}//判断是否清除
inline bool ch(int x,int y){
return x>=0&&x<5&&y>=0&&y<7;
}//判断是否越界
inline bool work(){
bool p=0;
for(int i=0;i<5;++i)
for(int j=0;j<7;++j){
if(!a[i][j])
continue;//有值
bool x=0;
if(ch(i-2,j)&&a[i][j]==a[i-2][j]&&ch(i-1,j)&&a[i][j]==a[i-1][j]&&ch(i+1,j)&&a[i][j]==a[i+1][j]&&ch(i+2,j)&&a[i][j]==a[i+2][j]){
x=1;
a[i-2][j]=a[i-1][j]=a[i+1][j]=a[i+2][j]=0;//11111
} else if(ch(i-1,j)&&a[i][j]==a[i-1][j]&&ch(i+1,j)&&a[i][j]==a[i+1][j]&&ch(i+2,j)&&a[i][j]==a[i+2][j]){
x=1;
a[i-1][j]=a[i+1][j]=a[i+2][j]=0;//01111
} else if(ch(i-2,j)&&a[i][j]==a[i-2][j]&&ch(i-1,j)&&a[i][j]==a[i-1][j]&&ch(i+1,j)&&a[i][j]==a[i+1][j]){
x=1;
a[i-2][j]=a[i-1][j]=a[i+1][j]=0;//11110
} else if(ch(i+1,j)&&a[i][j]==a[i+1][j]&&ch(i+2,j)&&a[i][j]==a[i+2][j]){
x=1;
a[i+1][j]=a[i+2][j]=0;//00111
} else if(ch(i-1,j)&&a[i][j]==a[i-1][j]&&ch(i+1,j)&&a[i][j]==a[i+1][j]){
x=1;
a[i-1][j]=a[i+1][j]=0;//01110
} else if(ch(i-2,j)&&a[i][j]==a[i-2][j]&&ch(i-1,j)&&a[i][j]==a[i-1][j]){
x=1;
a[i-2][j]=a[i-1][j]=0;//11100
}
if(ch(i,j-2)&&a[i][j]==a[i][j-2]&&ch(i,j-1)&&a[i][j]==a[i][j-1]&&ch(i,j+1)&&a[i][j]==a[i][j+1]&&ch(i,j+2)&&a[i][j]==a[i][j+2]){
x=1;
a[i][j-2]=a[i][j-1]=a[i][j+1]=a[i][j+2]=0;//11111
} else if(ch(i,j-1)&&a[i][j]==a[i][j-1]&&ch(i,j+1)&&a[i][j]==a[i][j+1]&&ch(i,j+2)&&a[i][j]==a[i][j+2]){
x=1;
a[i][j-1]=a[i][j+1]=a[i][j+2]=0;//01111
} else if(ch(i,j-2)&&a[i][j]==a[i][j-2]&&ch(i,j-1)&&a[i][j]==a[i][j-1]&&ch(i,j+1)&&a[i][j]==a[i][j+1]){
x=1;
a[i][j-2]=a[i][j-1]=a[i][j+1]=0;//11110
} else if(ch(i,j+1)&&a[i][j]==a[i][j+1]&&ch(i,j+2)&&a[i][j]==a[i][j+2]){
x=1;
a[i][j+1]=a[i][j+2]=0;//00111
} else if(ch(i,j-1)&&a[i][j]==a[i][j-1]&&ch(i,j+1)&&a[i][j]==a[i][j+1]){
x=1;
a[i][j-1]=a[i][j+1]=0;//01110
} else if(ch(i,j-2)&&a[i][j]==a[i][j-2]&&ch(i,j-1)&&a[i][j]==a[i][j-1]){
x=1;
a[i][j-2]=a[i][j-1]=0;//11100
}
if(x){
p=1;//有删除的
a[i][j]=0;
}//如果这个位置可以删除
}
return p;
}//删除
inline void down(){
for(int i=0;i<5;++i)
for(int j=0;j<6;++j){
if(!a[i][j]){
int qwq=-1;
for(int k=j+1;k<7;++k){
if(a[i][k]){
qwq=k;
break;
}//找到本行第一个不为 0 的数
}
if(qwq==-1)
break;//后面全是 0
a[i][j]=a[i][qwq];
a[i][qwq]=0;//掉下去
}
}
return;
}//掉下去
inline void dfs(int x){
if(x>n)
return;//步数炸了
if(!v1.empty()&&v2>v1)
return;
if(check()){
if(x!=n)
return;
v1=v2;
return;
}
// for(int i=0;i<5;++i){
// for(int j=0;j<7;++j)
// printf("%d ",a[i][j]);
// puts("");
// }
// puts("");
for(int i=0;i<5;++i)
for(int j=0;j<6;++j){//枚举交换的位置
for(int o=0;o<5;++o)
for(int p=0;p<7;++p)
b[o][p]=a[o][p];//记录答案
swap(a[i][j],a[i+1][j]);//交换
bool qwq=0;
while(work()){//可以删除
down();
qwq=1;
}
if(qwq){
v2.push_back(node({i,j,1}));
dfs(x+1);//搜索
v2.pop_back();//回溯
}
for(int o=0;o<5;++o)
for(int p=0;p<7;++p)
a[o][p]=b[o][p];//回溯
if(!a[i-1][j]){//左
swap(a[i][j],a[i+1][j]);//交换
bool qwq=0;
while(work()){//可以删除
down();
qwq=1;
}
if(qwq){
v2.push_back(node({i,j,-1}));
dfs(x+1);//搜索
v2.pop_back();//回溯
}
for(int o=0;o<5;++o)
for(int p=0;p<7;++p)
a[o][p]=b[o][p];//回溯
}
}
}
int main(){
scanf("%d",&n);
for(int i=0;i<5;++i){
int k,tot=0;
while(~scanf("%d",&k)&&k)
a[i][tot++]=k;//输入
}
dfs(0);//爆搜
if(v1.empty())
puts("-1");//无解
else
for(int i=0;i<n;++i)
printf("%d %d %d\n",v1[i].x,v1[i].y,v1[i].g);//输出答案
return 0;
}
回复
共 3 条回复,欢迎继续交流。
正在加载回复...