【洛谷1312】【NOIP2011DAY1T3】 Mayan游戏(模拟)

传送门

【题目分析】

T3考模拟有点意思,不过考场可能还真想不到自己错在哪了hhh

我的做法比较暴力,因为n不大,就直接枚举所有情况,有一些比较显然的性质:

1.当前位置有方块才交换(因为忘了这个WA了3个)

2.相同方块不用交换(剪枝?)

3.除非左边为空,否则不进行向左交换的操作。

然后就是一些小细节了嘻嘻嘻,看看代码就行,写的还算清真。

【代码~】

#include
using namespace std;
const int MAXN=11;
#define pii pair
#define mapa make_pair

int n,flag;
vector > ans;
struct MAP{
	int mp[MAXN][MAXN];
}ma;

int Read(){
	int i=0,f=1;
	char c=getchar();
	for(;(c>'9'||c<'0')&&c!='-';c=getchar());
	if(c=='-')  f=-1,c=getchar();
	for(;c>='0'&&c<='9';c=getchar())  i=(i<<3)+(i<<1)+c-'0';
	return i*f;
}

int check(MAP mp){
	for(int i=1;i<=5;++i)  if(mp.mp[i][1])  return 0;
	return 1;
}

int find(MAP &mp){
	int tag[MAXN][MAXN],flag1=0;
	memset(tag,0,sizeof(tag));
	for(int i=1;i<=5;++i){
		for(int j=1;j<=7;++j){
			if(mp.mp[i][j]&&!tag[i][j]){
				int id=j;
				while(mp.mp[i][j]==mp.mp[i][id+1])  ++id;
				if(id-j>=2){
					for(int k=j;k<=id;++k)  tag[i][k]=1;
				}
			}
		}
	}
	for(int i=1;i<=5;++i){
		for(int j=1;j<=7;++j){
			if(mp.mp[i][j]){
				int id=i;
				while(mp.mp[i][j]==mp.mp[id+1][j])  ++id;
				if(id-i>=2){
					for(int k=i;k<=id;++k)  tag[k][j]=1;
				}
			}
		}
	}
	for(int i=1;i<=5;++i){
		for(int j=1;j<=7;++j){
			if(tag[i][j])  flag1=1,mp.mp[i][j]=0;
		}
	}
	for(int i=1;i<=5;++i){
		for(int j=1;j<=7;++j){
			int id=j;
			while(id>=2&&!mp.mp[i][id-1])  mp.mp[i][id-1]=mp.mp[i][id],mp.mp[i][id]=0,--id;
		}
	}
	return flag1;
}

void dfs(int step,MAP mp){
	if(step==n){
		if(check(mp))  flag=1;
		return ;
	}
	if(flag)  return ;
	MAP mp1=mp;
	for(int i=1;i<=5;++i){
		for(int j=1;j<=7;++j){
			if(!mp.mp[i][j])  continue;
			if(i<5&&!mp.mp[i+1][j]){
				mp.mp[i+1][j]=mp.mp[i][j];
				int id=j;
				while(mp.mp[i][id+1])  mp.mp[i][id]=mp.mp[i][id+1],++id;
				mp.mp[i][id]=0;
				id=j;
				while(!mp.mp[i+1][id-1]&&id>=2)  mp.mp[i+1][id-1]=mp.mp[i+1][id],mp.mp[i+1][id]=0,--id;
				while(find(mp));
				
				ans.push_back(mapa(mapa(i,j),1));
				dfs(step+1,mp);
				if(flag)  return ;
				ans.pop_back();
				mp=mp1;
			}
			if(i<5&&mp.mp[i+1][j]&&mp.mp[i][j]!=mp.mp[i+1][j]){
				swap(mp.mp[i+1][j],mp.mp[i][j]);
				while(find(mp));
				ans.push_back(mapa(mapa(i,j),1));
				dfs(step+1,mp);
				if(flag)  return ;
				ans.pop_back();
				mp=mp1;
			}
			if(i>1&&!mp.mp[i-1][j]){
				mp.mp[i-1][j]=mp.mp[i][j];
				int id=j;
				while(mp.mp[i][id+1])  mp.mp[i][id]=mp.mp[i][id+1],++id;
				mp.mp[i][id]=0;
				id=j;
				while(!mp.mp[i-1][id-1]&&id>=2)  mp.mp[i-1][id-1]=mp.mp[i-1][id],mp.mp[i-1][id]=0,--id;
				while(find(mp));
				ans.push_back(mapa(mapa(i,j),-1));
				dfs(step+1,mp);
				if(flag)  return ;
				ans.pop_back();
				mp=mp1;
			}
		}
	}
}

int main(){
	n=Read();
	for(int i=1;i<=5;++i){
		int x=Read(),id=1;
		while(x)  ma.mp[i][id++]=x,x=Read();
	}
	dfs(0,ma);
	if(!flag){puts("-1");return 0;}
	for(int i=0;i

 

你可能感兴趣的:(————基础算法————,模拟)