1 solutions

  • 0
    @ 2023-10-20 20:10:45

    难度: 绿

    算法: 最短路,广度优先搜索

    说句实话,这题真的是太【数据删除】了。输出最小操作次数就算了,还让我们输出操作序列,还要输出字典序最小的,致使我调了 44 小时。赛前练最短路结果拿这种题恶心我,一本通我谢谢你。

    一眼最短路。

    观察到这题有一个不错的性质:魔板至多有 8!=403208!=40320 种状态,于是每种状态建一个点,每种操作连一条有向边,跑最短路即可。你可能需要多加一个关键字表示操作序列。

    • @ 2023-10-20 20:13:46

      鉴于本题代码量极大,在此放上代码,调不过去的同学可以参考。

      #include<bits/stdc++.h>
      using namespace std;
      int n,k[8],cnt=0,c,u,v,w,tp,dis[41000],vis[41000];
      string s,sv[41000];
      map<string,int> m;
      struct node{
      	int u,dis,ty;
      	string ans;
      	bool operator > (const node& a) const {return dis!=a.dis?dis>a.dis:ans<a.ans;}
      }h;
      vector<node> e[130000];
      priority_queue<node,vector<node>,greater<node> > q;
      string opa(string a){
      	string re="";
      	re=re+a[7]+a[6]+a[5]+a[4]+a[3]+a[2]+a[1]+a[0];
      	return re;
      }
      string opb(string a){
      	string re="";
      	re=re+a[3]+a[0]+a[1]+a[2]+a[5]+a[6]+a[7]+a[4];
      	return re;
      }
      string opc(string a){
      	string re="";
      	re=re+a[0]+a[6]+a[1]+a[3]+a[4]+a[2]+a[5]+a[7];
      	return re;
      }
      void build(int le,int ri,int te){
      	h.u=ri,h.ans=char(te+'A');
      	e[le].push_back(h);
      	return ;
      }
      int main(){
      	memset(dis,0x3f3f3f,sizeof(dis));
      	h.dis=1;
      	for(int i=0;i<8;i++) k[i]=i+1;
      	do{
      		s="";
      		for(int i=0;i<8;i++) s=s+char(k[i]+'0');
      		m[s]=++cnt;
      	}while(next_permutation(k,k+8));
      	for(int i=0;i<8;i++) k[i]=i+1;
      	do{
      		s="";
      		for(int i=0;i<8;i++) s=s+char(k[i]+'0');
      		build(m[s],m[opa(s)],0);
      		build(m[s],m[opb(s)],1);
      		build(m[s],m[opc(s)],2);
      	}while(next_permutation(k,k+8));
      	s="";
      	for(int i=0;i<8;i++) scanf("%d",&k[i]),s=s+char(k[i]+'0');
      	c=m[s];
      	dis[1]=0;
      	h.u=1,h.dis=0,h.ans="";
      	q.push(h);
      	while(!q.empty()){
      		u=q.top().u;
      		q.pop();
      		if(vis[u]==1) continue;
      		vis[u]=1;
      		for(int i=0;i<int(e[u].size());i++){			
      			s=sv[u];
      			v=e[u][i].u,w=e[u][i].dis,s=s+e[u][i].ans;
      			if(dis[v]>dis[u]+w||(dis[v]==dis[u]+w&&sv[v]>s)){
      				dis[v]=dis[u]+w,sv[v]=s;
      				h.u=v,h.dis=dis[v],h.ans=s;
      				q.push(h);
      			}
      		}
      	}
      	printf("%d\n",dis[c]);
      	cout<<sv[c];
      	return 0;
      }
      
  • 1

Information

ID
29
Time
1000ms
Memory
512MiB
Difficulty
8
Tags
# Submissions
18
Accepted
6
Uploaded By