HDU 3220 IDA*搜索 || BFS

来源:互联网 发布:北京三一重工java招聘 编辑:程序博客网 时间:2024/05/21 17:50

给出一个16个点所构成的图形,分别由0,1组成,每次操作可以任选其中相连的两个点(必须一个为0,一个为1),进行0,1,交换

问3步内是否可以把图形变成:0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1状态

若不行,输出more


状压存储图形状态。ida*搜索  或者 BFS都行


IDA*搜索

#include "stdio.h"#include "string.h"const int b[]={0,1,2,4,8,16,32,64,128,256,512,1024,2048,4096,8192,16384,32768,65536};const int adj[17][5]={    {0,0,0,0,0},    {0,2,3,5,9}, //1    {0,1,4,6,10}, //2    {0,1,4,7,11}, //3    {0,2,3,8,12}, //4    {0,1,6,7,13}, //5    {0,2,5,8,14}, //6    {0,3,5,8,15}, //7    {0,4,6,7,16}, //8    {0,1,10,11,13}, //9    {0,2,9,12,14}, //10    {0,3,9,12,15}, //11    {0,4,10,11,16}, //12    {0,5,9,14,15}, //13    {0,6,10,13,16}, //14    {0,7,11,13,16}, //15    {0,8,12,14,15} //16};int ans,flag,aim;int mark[70010];int cal(int x){    int i,cnt;    cnt=0;    for (i=1;i<=8;i++)        if ((x&b[i])!=0)        cnt++;    return cnt;}void dfs(int cur,int n){    int next,x,cnt,i,j;    if (cur==aim)    {        flag=1;        return ;    }    if (flag==1)        return ;    cnt=0;    for (i=1;i<=8;i++)        if ((cur&b[i])!=0) cnt++;    if (n+cnt>ans)        return ;    for (i=1;i<=16;i++)    {        x=cur&b[i];        if (x!=0)        for (j=1;j<=4;j++)        {            x=cur&b[adj[i][j]];            if (x==0)            {                next=cur;                next^=b[i];                next^=b[adj[i][j]];                if (mark[next]==0)                {                    mark[next]=1;                    dfs(next,n+1);                    mark[next]=0;                }            }        }    }}int main(){    int t,Case,i,status,cnt,x;    scanf("%d",&t);    Case=1;    memset(mark,0,sizeof(mark));    while (t--)    {        status=aim=cnt=0;        for (i=1;i<=16;i++)        {            scanf("%d",&x);            if (i<=8) cnt+=x;            status+=x*b[i];        }        for (i=9;i<=16;i++)            aim+=b[i];        printf("Case #%d: ",Case++);        if (aim==status)        {            printf("0\n");            continue;        }        if (cnt>3)        {            printf("more\n");            continue;        }        ans=0;        while(1)        {            ans++;            flag=0;            if (ans==4) break;            mark[status]=1;            dfs(status,0);            mark[status]=0;            if (flag==1)                break;        }        if (ans==4)            printf("more\n");        else            printf("%d\n",ans);    }    return 0;}


BFS

#include "stdio.h"#include "string.h"#include "queue"using namespace std;const int b[]={0,1,2,4,8,16,32,64,128,256,512,1024,2048,4096,8192,16384,32768,65536};const int adj[17][5]={    {0,0,0,0,0},    {0,2,3,5,9}, //1    {0,1,4,6,10}, //2    {0,1,4,7,11}, //3    {0,2,3,8,12}, //4    {0,1,6,7,13}, //5    {0,2,5,8,14}, //6    {0,3,5,8,15}, //7    {0,4,6,7,16}, //8    {0,1,10,11,13}, //9    {0,2,9,12,14}, //10    {0,3,9,12,15}, //11    {0,4,10,11,16}, //12    {0,5,9,14,15}, //13    {0,6,10,13,16}, //14    {0,7,11,13,16}, //15    {0,8,12,14,15} //16};int ans,flag,aim;int mark[70010];int cal(int x){    int i,cnt;    cnt=0;    for (i=1;i<=8;i++)        if ((x&b[i])!=0) cnt++;    return cnt;}int bfs(int cur){    int i,j,next;    queue<int>q;    q.push(cur);    memset(mark,-1,sizeof(mark));    mark[cur]=0;    while (!q.empty())    {        cur=q.front();        q.pop();        if (mark[cur]==3) continue;        for (i=1;i<=16;i++)            if ((cur&b[i])!=0)            for (j=1;j<=4;j++)            if ((cur&b[adj[i][j]])==0)            {                next=cur;                next^=b[i];                next^=b[adj[i][j]];                if (mark[next]==-1 && cal(next)+mark[cur]<=3)                {                    mark[next]=mark[cur]+1;                    if (next==aim) return mark[next];                    q.push(next);                }            }    }    return -1;}int main(){    int t,Case,i,status,cnt,x;    scanf("%d",&t);    Case=1;    aim=0;    for (i=9;i<=16;i++)        aim+=b[i];    while (t--)    {        status=cnt=0;        for (i=1;i<=16;i++)        {            scanf("%d",&x);            if (i<=8) cnt+=x;            status+=x*b[i];        }        printf("Case #%d: ",Case++);        if (aim==status)        {            printf("0\n");            continue;        }        if (cnt>3)        {            printf("more\n");            continue;        }        ans=bfs(status);        if (ans==-1)            printf("more\n");        else            printf("%d\n",ans);    }    return 0;}




0 0