Pro
[2020-2021 ICPC, NERC, Northern Eurasia Onsite]K题
Sol
这个题一看爆搜就可以做(但是我还是纳闷自己为什么A它花了这么久
需要注意的一点就是:如何判断这个状态出现过(即如果实现vis数组的功能)
很自然而然的想到,1000位数字肯定不能直接用数字,就考虑map
但是我前几遍的代码map的first的类型都是string 所以导致了错误
后面改成了vector很好的实现了我想要的效果
然后其实把vector作为dfs的参数也可以节省好多时空
关于本题的思考:
既vis数组之后可以用map存更大的状态
map配合vector能表示的状态可能会更优…
官方题解
Code
#include<iostream>
#include<cstdio>
#include<queue>
#include<cstring>
#include<string>
#include<algorithm>
#include<cmath>
#include<vector>
#include<map>
using namespace std;
typedef long long LL;
#define PI acos(-1)
#define INF 9223372036854775807
#define eps 1e-7
#define L 100005
#define Fo(i,a,b) for(LL i=(a); i<=(b); i++)
#define Ro(i,b,a) for(LL i=(b); i>=(a); i--)
#define Ms(a,b) memset((a),(b),sizeof(a))
#define _ceil(_,__) (_+(__-1))/__
#define debug(_) cout<<endl<<"d::"<<_<<endl<<endl
#define type(_) typeid(_).name()
inline LL read() {
LL x = 0, f = 1;char c = getchar();
while (!isdigit(c)) { if (c == '-')f = -f;c = getchar(); }
while (isdigit(c)) x = (x << 1) + (x << 3) + (c ^ 48ll), c = getchar();
return x * f;
}
LL n , x , ans = INF;
map<vector<LL> , LL>mp;
vector<LL> s;
void dfs(vector<LL>t , LL cnt) {
LL flag = 0;
Fo(i,0,2*n-1)
if(t[i]!=i+1) {
flag = 1;
break;
}
if(!flag) {
ans = min(ans , cnt);
return ;
}
vector<LL>m1;
vector<LL>m2;
Fo(i,n,2*n-1) m2.push_back(t[i]);
Fo(i,0,n-1) m2.push_back(t[i]);
for(int i=0; i<2*n; i+=2) {
m1.push_back(t[i+1]);
m1.push_back(t[i]);
}
if(!mp[m1]) {
mp[m1] = 1;
dfs(m1,cnt+1);
mp[m1] = 0;
}
if(!mp[m2]) {
mp[m2] = 1;
dfs(m2,cnt+1);
mp[m2] = 0;
}
}
int main() {
// freopen("data.txt","r",stdin);
n=read();
Fo(i,1,2*n) {
x=read();
s.push_back(x);
}
mp[s] = 1;
dfs(s,0);
printf("%lld",(ans==INF)?(-1):ans);
return 0;
}