现在的位置: 首页 > 综合 > 正文

UVA – 1533 (Moving Pegs)

2019年04月04日 ⁄ 综合 ⁄ 共 1908字 ⁄ 字号 评论关闭

思路简单,把状态看成一个长十五的01串,总状态为(2^15),以判断每个小球可否转移,转移的费时接近(3*11*4)大概最坏七八百万算法;总共输入为1-15打表可过;

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <vector>
using namespace std;
const int maxn = 16;

vector<int> a[maxn][7];
int deg[maxn],n;
const int b[11][6]={
{1,2,4,7,11},
{3,5,8,12},
{6,9,13},
{10,14},
{2,3},
{4,5,6},
{7,8,9,10},
{1,3,6,10,15},
{2,5,9,14},
{4,8,13},
{7,12}
};
void init(){
for(int i=1;i<=15;i++){

           int& cnt=deg[i];
           cnt=0;
           for(int j=0;j<11;j++){
                for(int k=0;k<6;k++){
                      if(b[j][k]==i){
                           if(b[j][k+1]!=0){
                               for(int p=k+1;b[j][p]!=0;p++)
                                  a[i][cnt].push_back(b[j][p]);
                                  cnt++;
                           }
                      }
                }
           }

            for(int j=0;j<11;j++){
                for(int k=4;k>=0;k--){
                      if(b[j][k]==i){
                           if(k>0){
                               for(int p=k-1;p>=0;p--)
                                  a[i][cnt].push_back(b[j][p]);
                                  cnt++;
                           }
                      }
                }
            }
}
}
void show(int s){
for(int i=14;i>=0;i--) if((s>>i)&1) cout<<"1";
else cout<<"0";
cout<<endl;
}
const  int N = (1<<15)+2;
struct node{
int from,to;
node(int a=0,int b=0) :from(a),to(b){}
bool operator < (const node& rhs)const{
return from < rhs.from ||from == rhs.from && to<rhs.to;}
};
node act[N];
int vis[N],S,goal_state,q[N*10],dist[N];
int bfs(){
int s =((1<<15)-1)&(~(1<<(S-1)));
for(int i=0;i<(1<<15);i++) vis[i]=10000;
for(int i=0;i<(1<<15);i++) act[i]=node(16,16);
show(s);
q[0]=s; vis[s]=0;
dist[0]=-1;
int front_=0,rear=1;
while(front_<rear){
      int& u = q[front_];
      if(u == goal_state){
            return vis[u];
      }
      for(int i=0;i<15;i++) if((u>>i)&1){

            for(int j=0;j<deg[i+1];j++){

                int ok=0;
                for(int k=0;k<a[i+1][j].size();k++){
                     if(!((u>>(a[i+1][j][k]-1))&1)) {ok=1; break;}
                }

                int& v=q[rear]; v=u;

                if(ok){
                    v=v&(~(1<<(i)));
                    int posi ;
                    for(int k=0;k<a[i+1][j].size();k++){
                     if(!((v>>(a[i+1][j][k]-1))&1)){
                             v|=1<<(a[i+1][j][k]-1); posi=a[i+1][j][k];
                             break;
                     }
                     else v=v&(~(1<<(a[i+1][j][k]-1)));
                    }
                     if(vis[v]>vis[u]+1 || vis[v]==vis[u]+1 && node(i+1,posi)<act[v]){
                            dist[v]= u;
                            act[v] = node(i+1,posi);
                            vis[v] =vis[u]+1;
                            rear++;
                     }
                }
            }
      }
      front_++;
}
return -1;
}

int main()
{
    init();
    int T;
    scanf("%d",&T);
    while(T--){
          scanf("%d",&S);
          goal_state =(1<<(S-1));
          int ans = bfs();
          if(ans == -1) {printf("IMPOSSIBLE\n"); continue;}
          else printf("%d\n",ans);
          print_ans(goal_state);
    }
    return 0;

}

抱歉!评论已关闭.