您的位置:首页 > 其它

蓝桥杯-由卡片换位引发的优化问题

2016-08-09 20:45 405 查看
卡片问题,之前的我的代码使用的是map,搜索效率不高。

现由群里的一位大牛给出的一个由(康拓展开的状态编码优化算法)

感谢这位“追梦”大牛

#include <iostream>

#include <cstdio>

#include <cstring>

#include <queue>

using namespace std;

//状态结构体

struct State

{

 int value[6];

 int dist;

};

int be,en;  //be表示A所在位置,en代表B所在位置

int fact[6];  //用于初始化阶乘的值

//阶乘值的初始化

void init()

{

 int i;

 fact[0]=1;

 for(i=1;i<6;i++)

  fact[i]=fact[i-1]*i;

}

int dp[6][6];  //动态规划,用于记录小于的个数(这里可以进一步优化,因为多余1个的数只有0),不失一般性,这里用dp[i][j]记录下标i的数后面数字j的个数

//dp数组的初始化

void getLessNum(int s[])

{

 int i,j;

 memset(dp,0,sizeof(dp));

 for(i=4;i>=0;i--)

 {

  for(j=0;j<4;j++)

   dp[i][j]+=dp[i+1][j];

  dp[i][s[i+1]]++;

 }

}

//这是将状态编码的方法,返回编码值,利用康托展开

int getMass(int s[])

{

 int i,j,ret=0,div=1,less=0;

 getLessNum(s);

 for(i=0;i<5;i++)

 {

  less=0;

  div=1;

  for(j=0;j<4;j++) if(s[i]>j)

  {

   div*=fact[dp[i][j]];

   less+=dp[i][j];

  }

  ret+=less*fact[5-i]/div;

 }

 return ret;

}

//这里是将对应编码转化为对应的状态,即逆康托

State massToState(int mass)

{

 int i=0,j,be=0,tmass=mass;

 State ret;

 int num[4]={3,1,1,1};

 while(i<6)

 {

  for(j=be;j<=3;j++) if(num[j])

  {

   int tnum;

   if(!j) tnum=fact[5-i]/fact[num[j]-1];

   else tnum=fact[5-i]/fact[num[0]];

   if(tnum>=tmass)

   {

    ret.value[i]=j;

    num[j]--;

    i++;

    break;

   }

   else

   {

    tmass-=tnum;

   }

  }

 }

 return ret;

}

bool vis[120];  //这是判重数组,因为总状态数即A(6,6)/A(3,3)=120种

//这里是bfs的方向偏移数组

int dx[4]={-1,0,1,0}; 

int dy[4]={0,1,0,-1};

//这里判断(x,y)是否是合法的点

bool isExceed(int x,int y)

{

 return x>=0&&x<2&&y>=0&&y<3;

}

queue<State> q;  //bfs所用队列,这里用STL的queue实现

//bfs广度优先搜索,如果不能达到则返回-1

int bfs(int s_b[],int beMass)

{

 int i,j;

 memset(vis,false,sizeof(vis));

 State b;

 for(i=0;i<6;i++) b.value[i]=s_b[i];

 b.dist=0;

 vis[beMass]=true;

 q.push(b);

 while(!q.empty())

 {

  State n=q.front();

  q.pop();

  if(n.value[be]==2&&n.value[en]==1)

   return n.dist;

  for(i=0;i<6;i++) if(n.value[i]==3) break;

  int nx=i/3;

  int ny=i%3;

  for(j=0;j<4;j++)

  {

   int cnx=nx+dx[j];

   int cny=ny+dy[j];

   if(!isExceed(cnx,cny)) continue;

   int cni=cnx*3+cny;

   State np=n;

   int t=np.value[i];

   np.value[i]=np.value[cni];

   np.value[cni]=t;

   int cnMass=getMass(np.value);

   if(!vis[cnMass])

   {

    vis[cnMass]=true;

    np.dist=n.dist+1;

    q.push(np);

   }

  }

 }

 return -1;

}

int main()

{

 //freopen("test.in","r",stdin);

 int state_begin[6],i,j;

 char str[10];

 for(i=0;i<2;i++)

 {

  gets(str);

  for(j=0;j<3;j++)

  {

   if(str[j]=='A') {state_begin[3*i+j]=1;be=3*i+j;}

   else if(str[j]=='B') {state_begin[3*i+j]=2;en=3*i+j;}

   else if(str[j]==' ') state_begin[3*i+j]=3;

   else state_begin[3*i+j]=0;

  }

 }

 init();

 getLessNum(state_begin);

 int mass=getMass(state_begin);

 int ans=bfs(state_begin,mass);

 if(ans!=-1) printf("%d\n",ans);

 else printf("Impossible\n");

 return 0;

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: