社区讨论

全WA求助,网络上下载的四川省选数据包给出结果完全正确QWQ

P2324[SCOI2005] 骑士精神参与者 4已保存回复 4

讨论操作

快速查看讨论及其快照的属性,并进行相关操作。

当前回复
4 条
当前快照
1 份
快照标识符
@mi6ywgyw
此快照首次捕获于
2025/11/20 13:05
4 个月前
此快照最后确认于
2025/11/20 13:05
4 个月前
查看原帖
如题求助QWQ
CPP
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
int succeeded;
int T,ch,mp[5][5],fin[5][5]={
	{1,1,1,1,1},
	{0,1,1,1,1},
	{0,0,2,1,1},
	{0,0,0,0,1},
	{0,0,0,0,0}
};
int x[8]={1,-1,1,-1,2,-2,2,-2};
int y[8]={2,-2,-2,2,1,-1,-1,1};
inline int evaluate(){
	int sum=0;
	for(int i=0;i<5;++i){
		for(int j=0;j<5;++j){
			if(mp[i][j]!=fin[i][j]){
				sum++;
			}
		}
	}
	//最理想情况:交换一步匹配一步 
	return sum;
}
void dfs(int pos_x,int pos_y,int step,int lim,int las){
	if(step==lim){
		if(!evaluate()){
			//完全匹配!
			succeeded=true;
			return; 
		}		
	}

	//如果超出限制
	//注意还要考虑最后一步交换可以换两个的情况 
	//evaluate代表最少的最理想步数,如果加上这个步数依然无法完成,则显然失败。
	int to_x,to_y;
	for(int i=0;i<8;++i){
		if(succeeded){
			return;
		}//已经成功->避免进一步搜索 
		if(i/2==las/2 && i!=las){
			continue;
		}//如果是上一步的反操作则显然不可以 
		to_x=pos_x+x[i];
		to_y=pos_y+y[i];
		if(5<=to_x || to_x<0 || 5<=to_y || to_y<0){
			continue;
		}//上下界剪枝
		swap(mp[pos_x][pos_y],mp[to_x][to_y]);
		if(evaluate()+step<=lim){
			dfs(to_x,to_y,step+1,lim,i);
		} 
		swap(mp[pos_x][pos_y],mp[to_x][to_y]);  
	} 
}
int main(){
	scanf("%d",&T);
	while(T--){
		succeeded=false;
		int bg_x=0,bg_y=0;
		for(int i=0;i<5;++i){
			for(int j=0;j<5;++j){
				do{
					ch=getchar();
				}while(ch==' '||ch=='\n');
				if(ch=='*'){
					//如果当前位置空位
					bg_x=i;
					bg_y=j;
					mp[i][j]=2;
				}else{
					//如果是黑白棋 
					mp[i][j]=ch-'0';
				}
				 
			}
		}
//		for(int i=0;i<5;++i){
//			for(int j=0;j<5;++j){
//				printf("%d ",mp[i][j]);
//			}
//			printf("\n");
//		}
		for(int i=0;i<=15;++i){
			dfs(bg_x,bg_y,0,i,10);
			//从[bg_x,bg_y]开始,步数限制为i 
			if(succeeded){
				printf("%d\n",i);
				break;
			}
		}
		if(!succeeded){
			printf("-1\n");
		}
	}
}

回复

4 条回复,欢迎继续交流。

正在加载回复...