zoukankan      html  css  js  c++  java
  • 互斥的数(codevs 1553)

    题目描述 Description

    有这样的一个集合,集合中的元素个数由给定的N决定,集合的元素为N个不同的正整数,一旦集合中的两个数x,y满足y = P*x,那么就认为x,y这两个数是互斥的,现在想知道给定的一个集合的最大子集满足两两之间不互斥。

    输入描述 Input Description

    输入有多组数据,每组第一行给定两个数N和P(1<=N<=10^5, 1<=P<=10^9)。接下来一行包含N个不同正整数ai(1<=ai<=10^9)。

    输出描述 Output Description

    输出一行表示最大的满足要求的子集的元素个数。

    样例输入 Sample Input

    4 2

    1 2 3 4

    样例输出 Sample Output

    3

    /*
      改了两个小时,把int改成long long 就对了,我晕…… 
      做法:由于对于每个数,和它互斥的数只有一个,所以可以找到和它互斥的数,然后建一条边,
            建边式统计入度,这样很多点就会成为一条链。对于每条链,如果它有tot个节点,我们
            最多能取 (tot-1)/2 个点,统计总点数。 
    */
    #include<cstdio>
    #include<iostream>
    #include<algorithm>
    #include<vector>
    #define ll long long
    #define M 100010
    using namespace std;
    ll n,p,a[M],in[M],tot;
    vector<ll> grap[M];
    void dfs(int x)
    {
        tot++;
        for(ll i=0;i<grap[x].size();i++)
          dfs(grap[x][i]);
    }
    int main()
    {
        cin>>n>>p;
        for(ll i=1;i<=n;i++)
          cin>>a[i];
        sort(a+1,a+n+1);
        for(ll i=1;i<=n;i++)
        {
            if(a[i]*p>1e9)continue;
            ll pos=lower_bound(a+i+1,a+n+1,a[i]*p)-a;
            if(pos>i&&pos<=n&&a[i]*p==a[pos])
              grap[i].push_back(pos),in[pos]++;
        }
        ll ans=0;
        for(ll i=1;i<=n;i++)
          if(!in[i])
          {
              tot=0;dfs(i);
              ans+=(tot+1)/2;
          }
        cout<<ans;
        return 0;
    }
    View Code1
    /*
      另一种做法 hash
    */
    #include<iostream>
    #include<algorithm>
    #include<cstdio>
    #define mod 1358717
    #define M 100010
    #define ll long long
    using namespace std;
    ll head[mod+10],a[M],n,m,cnt;
    struct node
    {
        ll v,pre;
    };node e[M];
    void add(ll x,ll v)
    {
        ++cnt;
        e[cnt].v=v;
        e[cnt].pre=head[x];
        head[x]=cnt;
    }
    bool find(ll x,ll v)
    {
        for(ll i=head[x];i;i=e[i].pre)
          if(e[i].v==v)return true;
        return false;
    }
    int main()
    {
        cin>>n>>m;
        for(ll i=1;i<=n;i++)
          cin>>a[i];
        sort(a+1,a+n+1);
        ll ans=0;
        for(ll i=1;i<=n;i++)
        {
            if(find(a[i]%mod,a[i]))continue;
            ll v=a[i]*m;
            if(v<=1e9)add(v%mod,v);
            ++ans;
        }
        cout<<ans;
        return 0;
    }
    View Code2
  • 相关阅读:
    1033 To Fill or Not to Fill (25分)(贪心)
    CentOS(五)--Linux系统的分区概念
    Linux安装Oracle 11G过程(测试未写完)
    【VMware虚拟化解决方案】设计和配置VMware vCenter 5.5
    CentOS(四)--Linux系统的启动级别
    CentOS(三)--初识linux的文件系统以及用户组等概念
    CentOS(二)--初识linux的一些常用命令
    CentOS(一)--CentOS6.4环境搭建
    Linux c/c++图片传输功能(中级版)
    remote uptime 服务器程序
  • 原文地址:https://www.cnblogs.com/harden/p/5862247.html
Copyright © 2011-2022 走看看