80分 求助
查看原帖
80分 求助
398310
hundunqidian楼主2023/3/28 19:58

WA了8、9测试点 (以下代码已添加注释)

#include<bits/stdc++.h>
using namespace std;
int const X=510,XX=16;
int R,C,n,cnt;
char c[X][X];
struct node{
	int x,y,s; //“一s两吃” 
	/*s:
		bfs内用于标记步数;
		也用于标记仓库字母序 
	*/
};
node t[XX]; //记录仓库坐标 
bool cmp(node a,node b){ //字典序排序 
	return a.s<b.s;
}
bool check(int x,int y){ //判定bfs中的坐标是否出界 
	if(x<=0 || x>R || y<=0 || y>C || c[x][y]=='*'){
		return 0;
	}
	return 1;
}
string Min(string a,string b){ //比较字符串大小 
	if(a>b) return b;
	return a;
} 
int dir[4][2]={1,0,-1,0,0,1,0,-1}; //控制方向 
int dis[XX][XX],tmp[X][X]; //dis:每两点间距 
int f[(1<<XX)][XX],ans; //f:DP数组 ans:记录最小值 
void bfs(int a,int b){
	//bfs求一个点到其他点距离 
	queue<node> q;
	node now,nxt;
	now.x=a; now.y=b; now.s=0;
	q.push(now);
	bool p[X][X]={0};
	p[a][b]=1;
	while(!q.empty()){
		now=q.front();
		q.pop();
		for(int i=0;i<4;i++){
			nxt.x=now.x+dir[i][0];
			nxt.y=now.y+dir[i][1];
			nxt.s=now.s+1;
			if(check(nxt.x,nxt.y) && !p[nxt.x][nxt.y]){
				q.push(nxt);
				p[nxt.x][nxt.y]=1;
				if(c[nxt.x][nxt.y]>='A' && c[nxt.x][nxt.y]<='Z'){
					tmp[nxt.x][nxt.y]=nxt.s;
				}
			}
		}
	}
	return ;
}
string g[(1<<XX)][XX],ans_g; //g:记录顺序 ans_g:最小字典序答案 
int main() {
	ios::sync_with_stdio(0);
	cin.tie(0); cout.tie(0);
	cin>>R>>C>>n;
	for(int i=1;i<=R;i++){
		for(int j=1;j<=C;j++){
			cin>>c[i][j];
			if(c[i][j]>='A' && c[i][j]<='Z'){ //若字母,则记录入t中 
				t[++cnt].x=i; t[cnt].y=j; t[cnt].s=c[i][j]-'A';
			}
		}
	}
	sort(t+1,t+1+n,cmp); //排序 
	for(int i=1;i<=n;i++){ //求仓库间距 
		memset(tmp,0,sizeof(tmp));
		bfs(t[i].x,t[i].y);
		for(int j=1;j<=n;j++){
			dis[i-1][j-1]=tmp[t[j].x][t[j].y];
		}
	}
	memset(f,0x3f,sizeof(f));
	f[1][0]=0;
	g[1][0]="A"; 
	for(int i=3;i<(1<<n);i+=2){//状态压缩DP求解 
		for(int u=0;u<n;u++){
			if(i&(1<<u)){
				for(int v=1;v<n;v++){
					if(i&(1<<v)){
						if(f[i][v]>f[i^(1<<v)][u]+dis[u][v]){
							f[i][v]=f[i^(1<<v)][u]+dis[u][v];
							g[i][v]=g[i^(1<<v)][u]+char('A'+t[v+1].s);
						}
						else if(f[i][v]==f[i^(1<<v)][u]+dis[u][v]){
							g[i][v]=Min(g[i][v],g[i^(1<<v)][u]+char('A'+t[v+1].s));
						}
					}
				}
			}
		}
	}
	ans=INT_MAX; ans_g="Z";
	for(int i=1;i<n;i++){ //从结果中找最优 
		if(ans>f[(1<<n)-1][i]){
			ans=min(ans,f[(1<<n)-1][i]);
			ans_g=Min(ans_g,g[(1<<n)-1][i]);
		}
		else if(ans==f[(1<<n)-1][i]){
			ans_g=Min(ans_g,g[(1<<n)-1][i]);
		}
	}
	cout<<ans<<endl<<ans_g<<endl;
	return 0;
}
2023/3/28 19:58
加载中...