• UVA-1663 Purifying Machine (最大匹配数)


    题目大意:每一个01串中最多含有一个‘*’,‘*’既可表示0也可表示1,给出一些等长的这样的01串,问最少能用多少个这样的串表示出这些串。如:000、010、0*1表示000、010、001、011,最少只需用00*、01*这两个即可表示出来。

    题目分析:如果有两个串只有一个位置上的数字不同,就可以用*代替这个位置上的数,这样就能把两个串用一个串表示出来。因为要找最少的数目,当然‘*’用的越多越好,也就是说只需找出最多的对数,然后再加上不用‘*’表示的串的数目便是最小值。

    代码如下:

    # include<iostream>
    # include<cstdio>
    # include<vector>
    # include<cstring>
    # include<algorithm>
    using namespace std;
    
    vector<int>b;
    int vis[1005];
    int n,m,a[1500][1500],s[1500],t[1005];
    int A[11]={1,2,4,8,16,32,64,128,256,512,1024};
    
    void f(string p)
    {
        int r=0;
        for(int i=0;i<m;++i)
            r=r*2+p[i]-'0';
        b.push_back(r);
    }
    
    bool ok(int x,int y)
    {
        int z=x^y;
        for(int i=0;i<11;++i)
            if(z==A[i]) return true;
        return false;
    }
    
    void setG()
    {
        memset(a,0,sizeof(a));
        for(int i=0;i<n;++i)
            for(int j=i+1;j<n;++j)
                if(ok(b[i],b[j])) a[i][j]=a[j][i]=1;
    }
    
    bool match(int u)
    {
        for(int v=0;v<n;++v){
            if(!a[u][v]) continue;
            if(vis[v]) continue;
            vis[v]=1;
            if(t[v]==-1||match(t[v])){
                t[v]=u;
                s[u]=v;
                return true;
            }
        }
        return false;
    }
    
    void solve()
    {
        memset(s,-1,sizeof(s));
        memset(t,-1,sizeof(t));
        int ans=0;
        for(int i=0;i<n;++i)
            if(s[i]==-1){
                memset(vis,0,sizeof(vis));
                if(match(i)) ++ans;
            }
        ans/=2;
        for(int i=0;i<n;++i)
            if(t[i]==-1) ++ans;
        printf("%d
    ",ans);
    }
    
    int main()
    {
        string p;
        while(scanf("%d%d",&m,&n)&&(n+m))
        {
            b.clear();
            for(int i=0;i<n;++i){
                cin>>p;
                int j;
                for(j=0;j<m;++j) if(p[j]=='*') break;
                if(j==m) f(p);
                else{
                    p[j]='0';
                    f(p);
                    p[j]='1';
                    f(p);
                }
            }
            sort(b.begin(),b.end());
            n=unique(b.begin(),b.end())-b.begin();
            setG();
            solve();
        }
        return 0;
    }
    

      

  • 相关阅读:
    java+phantomjs实现动态网页抓取
    windows 安装 cordova
    windows系统安装 ionic
    windows系统 安装 mysql.fx
    安装 Navicat for MySQL
    windows 安装 MySQL
    调用百度地图api隐藏版权信息
    ExpressionChangedAfterItHasBeenCheckedError: Expression has changed after it was checked.
    Angular 调用百度地图API接口
    Angular 使用 frame 加载网络资源显示路径不安全问题
  • 原文地址:https://www.cnblogs.com/20143605--pcx/p/5140314.html
Copyright © 2020-2023  润新知