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
",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
",bfs());
    }
    return 0;
}

  

原文地址:https://www.cnblogs.com/sola1994/p/4369259.html