社区讨论

萌新刚学 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 条回复,欢迎继续交流。

正在加载回复...