csu 1536 Bit String Reordering(模拟 bfs+状态压缩)

 

http://acm.csu.edu.cn/OnlineJudge/problem.php?id=1536

题意: 输入n个只为 0或1 的数 形成一个排列

         再输入m个数 每个数代表 目标排列

       (样例

     1 0 0 1 0 1
1 3 2

目标排列有可能为
1 0 0 0 1 1 或 0 1 1 1 0 0
   )
每次只能移动相邻的数

         问最少几步达到

 

思路:1 纯模拟 

           对目标串分类讨论

          如果起始串和目标串上对应位置数字不一样

          swap(b[j],b[i]);

          ans+=j-i;

       

       2 bfs+状态压缩

         将起始串和两种可能的目标串状压 

         并bfs相邻状态 记录步数

         达到目标串状态时 输出结果      

 

模拟:

#include<iostream>

#include<cstdio>

#include<cstring>

#include<cmath>

#include<stdlib.h>

#include<algorithm>

using namespace std;

const int MAXN=20;

int a[MAXN],b[MAXN],num[MAXN],temp[MAXN],ans;

void swap(int &a,int &b)

{

    int temp;

    temp=a;

    a=b;

    b=temp;

}

int min(int a,int b)

{

    if(a>b) return b;

    else return a;

}

int main()

{

    int n,m,num0=0,num1=0,res1=0,res2=0;

    int minn=0x3f3f3f3f;

    scanf("%d %d",&n,&m);

    for(int i=1;i<=n;i++)

    {

        scanf("%d",&a[i]);

        if(a[i]==1) num1++;

        if(a[i]==0) num0++;

    }

    for(int i=1;i<=m;i++)

    {

        scanf("%d",&temp[i]);

        if(i%2==1) res1+=temp[i];

        if(i%2==0) res2+=temp[i];

    }

    if(res1==num1)

    {

        ans=0;

        memset(b,0,sizeof(b));

        for(int i=1;i<=n;i++) num[i]=a[i];

        int flag=1,cnt=1;

        for(int i=1;i<=m;i++)

        {

            for(int j=1;j<=temp[i];j++)

                b[cnt++]=flag;

            flag=!flag;

        }

        for(int i=1;i<=n;i++)

        {

            if(num[i]==b[i]) continue;

            else

            {

                for(int j=i+1;j<=n;j++)

                {

                    if(b[j]==!b[i])

                    {

                        swap(b[j],b[i]);

                        ans+=j-i;

                        break;

                    }

                }

            }

        }

        minn=min(ans,minn);

    }

    if(res1==num0)

    {

        ans=0;

        memset(b,0,sizeof(b));

        for(int i=1;i<=n;i++) num[i]=a[i];

        int flag=0,cnt=1;

        for(int i=1;i<=m;i++)

        {

            for(int j=1;j<=temp[i];j++)

                b[cnt++]=flag;

            flag=!flag;

        }

        for(int i=1;i<=n;i++)

        {

            if(num[i]==b[i]) continue;

            else

            {

                for(int j=i+1;j<=n;j++)

                {

                    if(b[j]==!b[i])

                    {

                        swap(b[j],b[i]);

                        ans+=j-i;

                        break;

                    }

                }

            }

        }

        minn=min(ans,minn);

    }

    printf("%d\n",minn);

    return 0;

}

 

bfs+状态压缩

#include <algorithm>

#include <iostream>

#include <cstdio>

#include <cstring>

#include <cmath>

#include <vector>

#include <map>

#define N 1000005

#define lson o<<1, l, m

#define rson o<<1|1, m + 1, r

#define mod 1000000007

using namespace std;

typedef long long LL;

 

int n,m;

int vis[100050];

int a[20],b[20],c[20];

int ans[2];

int st;

 

int bfs()

{

    int pre[100005];

    int begin = 0,end = 1;

    pre[0] = st;

    int t[100006];

    t[0] = 0;

    while(begin < end)

    {

        int w = pre[begin];

        if(w == ans[0] || w == ans[1])

        {

            return t[begin];

        }

        int i;

        int g = 1;

        int now;

        for(i = 0; i < n - 1; i++)

        {

            if(((w >> i) & 1) != ((w >>(i + 1)) & 1))

            {

                if(((w >> i) & 1) == 1)

                {

                    now = w + g;

                }

                else

                {

                    now = w - g;

                }

                if(vis[now] == 0)

                {

                    vis[now] = 1;

                    pre[end] = now;

                    t[end++] = t[begin] + 1;

                }

            }

            g *= 2;

        }

        begin++;

    }

} 

int main()

{

    while(scanf("%d %d",&n,&m)!=EOF)

    {

        int i,j;

        st = 0;

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

        {

            scanf("%d",&a[i]);

        }

        int g = 1;

        for(i = n - 1; i >= 0; i--)

        {

            st += a[i] * g;

            g *= 2;

        }

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

        {

            scanf("%d",&b[i]);

        }

        g = 0;j = 0;

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

        {

            for(int k = 0; k < b[i]; k++)

            {

                c[j++] = g;

            }

            g ^= 1;

        }

        ans[0] = ans[1] = 0;

        g = 1;

        for(i = n - 1; i >= 0; i--)

        {

            ans[0] += c[i] * g;

            g *= 2;

        }

        g = 1;j = 0;

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

        {

            for(int k = 0; k < b[i]; k++)

            {

                c[j++] = g;

            }

            g ^= 1;

        }

        g = 1;

        for(i = n - 1; i >= 0; i--)

        {

            ans[1] += c[i] * g;

            g *= 2;

        }        

        memset(vis,0,sizeof(vis));

        printf("%d\n",bfs());

    }

    return 0;

}

  

你可能感兴趣的:(String)