• 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;
    }
    

      

  • 相关阅读:
    【ARM-Linux开发】用VS2013+VELT-0.1.4进行海思平台 Linux内核 的开发
    【CUDA开发-并行计算】NVIDIA深度学习应用之五大杀器
    [ARM-Linux开发]Linux open函数
    [ARM-Linux开发]mknod命令使用
    [ARM-LInux开发]linux设备驱动makefile入门解析
    [ARM-Linux开发] 嵌入式 linux如何生成ko文件
    [ARM-Linux开发]Linux下加载.ko驱动模块的两种方法:insmod与modprobe
    [ARM-Linux开发] 主设备号--驱动模块与设备节点联系的纽带
    【视频开发】Gstreamer框架中使用gst-launch进行流媒体播放
    【视频开发】用GStreamer实现摄像头的采集和保存
  • 原文地址:https://www.cnblogs.com/sola1994/p/4369259.html
Copyright © 2020-2023  润新知