• topcoder srm 699 div1 -3


    1、两个长度为$n$的数组$a,b$,$0 leq a_{i} <2^{30}$。$b_{i}=-1$或者$b_{i}$为除$a_{i}$外其他数字的抑或值。现在给定$b$,如果不存在$a$,返回-1.否则输出$a$数组所有数字和的最小值。

    思路:一位一位考虑。当前考虑第$k$位。对于所有不知道的数字将它们看做一个数字0或者1。现在就是一个全是01的数组$c$,那么$c_{i}$^$c_{j}$=$A_{i}$^$A_{j}$。其中$A_{i}=(a_{i}$>>$k)$&1.然后假定$A_{0}=$0或者1进行判断即可。

    #include <stdio.h>
    #include <string.h>
    #include <string>
    #include <iostream>
    #include <vector>
    #include <set>
    #include <map>
    #include <queue>
    #include <algorithm>
    #include <stack>
    #include <assert.h>
    using namespace std;
    
    const int N=44;
    
    int n;
    vector<pair<int,int> > g[N];
    
    int a[N],m;
    int b[N];
    int c[N];
    
    int dfs(int t)
    {
        for(int i=0;i<(int)g[t].size();++i)
        {
            int v=g[t][i].first;
            int w=g[t][i].second;
            if(b[v]==-1)
            {
                b[v]=w^b[t];
                if(!dfs(v)) return 0;
            }
            else if(b[v]!=(w^b[t])) return 0;
        }
        return 1;
    }
    
    int get()
    {
        for(int i=0;i<m;++i) g[i].clear();
        for(int i=0;i<m;++i) {
            for(int j=i+1;j<m;++j) {
                g[i].push_back(make_pair(j,a[i]^a[j]));
                g[j].push_back(make_pair(i,a[i]^a[j]));
            }
        }
        int ans=m+1;
        for(int i=0;i<2;++i)
        {
            memset(b,-1,sizeof(b));
            b[0]=i;
            if(!dfs(0)) return -1;
            int all=0;
            for(int i=0;i<m;++i) all^=b[i];
    
            int ok=1;
    
            for(int i=0;i<m&&ok;++i)
            {
                if(a[i]!=(all^b[i])) ok=0;
            }
            if(!ok) continue;
    
            int tmp=0;
            for(int i=0;i<m;++i) tmp+=b[i];
            if(ans>tmp) ans=tmp;
        }
        if(ans==m+1) ans=-1;
        return ans;
    }
    
    int cal()
    {
        m=0;
        int k=0;
        for(int i=0;i<n;++i)
        {
            if(c[i]==-1) k=1;
            else a[m++]=c[i];
        }
        if(k)
        {
            ++m;
            a[m-1]=0;
            int p0=get();
            a[m-1]=1;
            int p1=get();
            if(p0==-1)
            {
                if(p1==-1) return -1;
                return p1;
            }
            else
            {
                if(p1==-1) return p0;
                return min(p0,p1);
            }
        }
        else
        {
            return get();
        }
    }
    
    class OthersXor
    {
    public:
        long long minSum(vector<int> x)
        {
            n=(int)x.size();
            long long sum=0;
            for(int i=0;i<30;++i)
            {
                for(int j=0;j<n;++j)
                {
                    if(x[j]==-1) c[j]=-1;
                    else c[j]=(x[j]>>i)&1;
                }
                int p=cal();
                if(p==-1) return -1;
                sum+=(1ll<<i)*p;
            }
            return sum;
        }
    };
    

      

    2、一个$N$个节点的有向图。给出$m$个数对$(a_{0},b_{0}),(a_{1},b_{1})...(a_{m-1},b_{m-1})$。两个节点$X,Y$有边当且仅当存在一个数对$(a_{i},b_{i})$使得$a_{i}$可整除$X$且$b_{i}$可整除$Y$。给定起点$s$终点$t$,求最短路。

    思路:将数对看做节点。第$i$个节点可以向第$j$个节点连边当且仅当$lcm(b_{i},a_{j})leq N$。

    #include <stdio.h>
    #include <string.h>
    #include <string>
    #include <iostream>
    #include <vector>
    #include <set>
    #include <map>
    #include <queue>
    #include <algorithm>
    #include <stack>
    #include <assert.h>
    using namespace std;
    
    
    vector<int> g[1005];
    int n;
    int s,t;
    
    
    queue<int> Q;
    int f[1005];
    
    int bfs()
    {
        memset(f,-1,sizeof(f));
        f[0]=0;
        Q.push(0);
        while(!Q.empty())
        {
            int u=Q.front(); Q.pop();
            for(int i=0;i<(int)g[u].size();++i)
            {
                int v=g[u][i];
                if(f[v]==-1)
                {
                    f[v]=f[u]+1;
                    Q.push(v);
                }
            }
        }
        if(f[t]!=-1) return f[t]-1;
        return f[t];
    }
    
    
    int gcd(int a,int b)
    {
        return !b?a:gcd(b,a%b);
    }
    
    class FromToDivisible
    {
    public:
        int shortest(int N,int S,int T,vector<int> a,vector<int> b)
        {
            n=(int)a.size();
            s=0;
            t=n+1;
            for(int i=0;i<n;++i) for(int j=0;j<n;++j) if(i!=j)
            {
                long long tmp=1ll*b[i]/gcd(b[i],a[j])*a[j];
                if(tmp<=N)
                {
                    g[i+1].push_back(j+1);
                }
            }
            for(int i=0;i<n;++i)
            {
                if(S%a[i]==0) g[0].push_back(i+1);
                if(T%b[i]==0) g[i+1].push_back(t);
            }
            return bfs();
        }
    };
    

      

  • 相关阅读:
    SPSS Clementine 数据挖掘入门 (2)
    Oracle与SQL Server数据库管理对比
    在SharePoint中修改AD用户密码的WebPart
    【html】html 特殊字符大全
    【javascript】csshover 解决 ie6 下 hover 兼容问题
    【css】纯 css 制作带三角的边框
    【javascript】无缝滚动——上下
    【css】利用小数解析差异解决浏览器兼容性问题
    【javascript】checkbox——类似邮箱全选功能(完整版)
    【javascript】无缝滚动——左右
  • 原文地址:https://www.cnblogs.com/jianglangcaijin/p/6860812.html
Copyright © 2020-2023  润新知