您的位置:首页 > 理论基础 > 计算机网络

2015北京赛区网络赛 Boxes

2015-09-21 21:34 429 查看
状压 bfs

预处理所有的情况(样例数为6000,太多,所以预处理)

先离散化一次

状态的表示为数字t

数字t的第i个数字上的数字为x,数字i在x位置上

用mp数组来存每个状态t

mp[t]表示t到终止状态的步数

记住要用数组来存,不要用map,因为的存的数字过多,map的查询不是o(n)的时间

要用数组
#include <cstdio>
#include <cstdlib>
#include <iostream>
#include <algorithm>
#include <cstring>
#include <climits>
#include <string>
#include <vector>
#include <cmath>
#include <stack>
#include <queue>
#include <set>
#include <map>
#include <sstream>
#include <cctype>
using namespace std;
typedef long long ll;
typedef pair<int ,int> pii;
#define MEM(a,b) memset(a,b,sizeof a)
#define CLR(a) memset(a,0,sizeof a);
const int inf = 0x3f3f3f3f;
const int MOD = 1e9 + 7;
//#define LOCAL
int End;
int a[10];
int b[10];
int mp[10000000];
map<int,int> mmp;
void init(){
int t=0;
for(int i=1;i<=7;i++){
t = 0;
for(int j=1;j<=i;j++){
t += pow(10,i-j)*j;
}
queue<int> q;
q.push(t);
mp[t]=1;
while(!q.empty()){
int x = q.front();
q.pop();
int top[10];
MEM(top,inf);
int a[10];
int cnt = i;
int re = x;
while(re){
a[cnt--] = re%10;
re/=10;
}
for(int j=1;j<=i;j++){
top[a[j]]=min(top[a[j]],j);
}
for(int j=1;j<=i;j++){
if(j-1>=1 && (top[j]<top[j-1] || top[j-1]==inf) && top[j]!=inf){
int s=0;
for(int t=1;t<=i;t++){
if(t==top[j]){
s = s*10 + j-1;
}
else s = s*10+a[t];
}
if(!mp[s]){
mp[s]=mp[x]+1;
q.push(s);
}
}
if(j+1<=i && (top[j]<top[j+1] || top[j+1]==inf) && top[j]!=inf){
int s=0;
for(int t=1;t<=i;t++){
if(t==top[j]){
s = s*10 + j+1;
}
else s = s*10+a[t];
}
if(!mp[s]){
mp[s]=mp[x]+1;
q.push(s);
}
}
}
}
}
}
int main()
{
#ifdef LOCAL
freopen("in.txt", "r", stdin);
//	freopen("out.txt","w",stdout);
#endif
init();
int t;cin >> t;
while(t--){
End = 0;
int n;cin >> n;
for(int i=1;i<=n;i++){
scanf("%d",&a[i]);
b[i]=a[i];
}
sort(a+1,a+1+n);
for(int i=1;i<=n;i++){
mmp[a[i]]=i;
}
for(int i=1;i<=n;i++){
b[i]=mmp[b[i]];
}
for(int i=1;i<=n;i++){
End+=(int)pow(10,n-b[i])*i;
}
printf("%d\n",mp[End]-1);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: