灵异事件,样例超时,却AC了!
查看原帖
灵异事件,样例超时,却AC了!
1073995
Saint_ying_xtf楼主2024/1/17 23:00
//Author: gsczl71
//Copyright (c) 2024 gsczl71 All rights reserved.

#include<bits/stdc++.h>
#define ll long long
#define i128 __int128
#define ull unsigned long long
#define pii pair<int,int>
#define pll pair<long long, long long>
#define fs first
#define sc second
#define endl '\n'
#define debug puts("AK IOI")
#define re register
#define pb push_back
#define mem(a,x) memset((a),(x),sizeof(a))
using namespace std;
//#define int long long
const int mod = 1e9 + 7;
//const int mod = 998244353;
const int inf = 0x3f3f3f3f, N = 2e5 + 5, M = 2e5 + 5;
const ll linf = 0x3f3f3f3f3f3f3f3f;
int n, m;
vector<int> s, e; //分别表示一开始的编号和最后目标的编号。
map<vector<int>, int> ans[3]; //记录是从头还是从后vector这个状态的最小贡献。
map<vector<int>, int> vis; //是否走过
int change(int x,int y){return (x-1)*m+y-1;}
vector<int> sol(vector<int> v, int x) {//对每一种操作进行转移
	//对于普通的操作:
	for(int i = 1;i <= (n-1)/2;i++){
		for(int j = 1;j <= m-1;j++){
			swap(v[change(i+(x&1),j+((x/2)&1))] , v[change(n-i+(x&1),m-j+((x/2)&1))]);
		}
	}
	//如果是奇数的话,还要换一下中间的一行
	
	if(n>2 && (n-1) & 1){//算中间的位置
		for(int i = 1;i <= (m-1)/2;i++){
			swap(v[change((n+1)/2+(x&1),i+((x/2)&1))],v[change(n-(n+1)/2+(x&1),m-i+((x/2)&1))]);
		}
	}
	
	return v;
}
void dfs(vector<int> v, int x, bool flag) {
	if (!vis[v])vis[v] = 1, ans[flag][v] = x;
	else ans[flag][v] = min(ans[flag][v], x);
	if (x == 10) return ;//meet in the middle 控制折半搜索 
	for (int i = 0 ; i < 4; i++) 
		dfs(sol(v, i), x + 1, flag);//dfs
//	cout<<x<<endl;
}

void solve() {
	cin >> n >> m;
	for (int i = 1; i <= n * m; i++) {
		int x;
		cin >> x;
		s.pb(x), e.pb(i);
	}
	dfs(s,0,0);
	vis.clear();
	dfs(e,0,1);
	
	int res=inf;
	for(auto it:ans[0]){
		if(vis[it.first]){
			res=min(res,ans[1][it.first] + it.second);
		}
	}
	
	if(res > 20) cout<<-1;
	else cout<<res;

}
signed main() {
	ios::sync_with_stdio(false), cin.tie(nullptr), cout.tie(nullptr);
	int T = 1;
//	cin >> T;
	while (T--) solve();
	return 0;
}

2024/1/17 23:00
加载中...