• Kingdom of Obsession---hdu5943(二分匹配)


    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5943

    题意:给你两个数n, s 然后让你判断是否存在(s+1, s+2, s+3, ... , s+n )的任意排列方式使得每个数都满足当前数num,与num所在位置 pos  形成num%pos=0;

    例如 n = 4 , s = 11

    num = {13, 14, 15, 12}

    pos =  {1,    2,   3,    4}

    每个num与之对应的pos都是num%pos = 0;的关系

    分为两种情况:当s+1>n 时,我们只需看第二个数组中是否含有>=2个素数即可, 因为1只有1个;

    当s+1<=n时,两个区间有重叠,我们可以忽略这些重叠部分,看两端的即可,其实就是交换一下n,s的值; 

    其实就是两个数组建图,然后求最大匹配是否为1,当然n比较大,但是连续600个数中间一定包含>=2个素数,所以当n<600时可以用二分匹配来做;

    #include<stdio.h>
    #include<string.h>
    #include<iostream>
    #include<vector>
    using namespace std;
    typedef long long LL;
    const int oo = 0xfffffff;
    const int N = 615;
    
    int used[N], vis[N], n, s;
    vector<int> G[N];
    
    bool Find(int u)
    {
        int len=G[u].size();
        for(int i=0; i<len; i++)
        {
            int v = G[u][i];
            if(!vis[v])
            {
                vis[v] = 1;
                if(!used[v] || Find(used[v]))
                {
                    used[v] = u;
                    return true;
                }
            }
        }
        return false;
    }
    
    int main()
    {
        int T, t = 1;
        scanf("%d", &T);
        while(T --)
        {
            scanf("%d %d", &n, &s);
    
            if(s+1 <= n)///忽略中间重合的部分;
                swap(s, n);
    
            if(n > 600)///因为连续600个数中一定有>=2个素数, 1只有一个,所以结果都是No;
            {
                printf("Case #%d: No
    ", t++);
                continue;
            }
    
            for(int i=0; i<=n; i++)
                G[i].clear();
    
            for(int i=1; i<=n; i++)
            {
                for(int j=1; j<=n; j++)
                {
                    if((s+i)%j == 0)///说明s+i是j的倍数;
                        G[i].push_back(j);
                }
            }
            memset(used, 0, sizeof(used));
            int ans = 0;
            for(int i=1; i<=n; i++)
            {
                memset(vis, 0, sizeof(vis));
                ans += Find(i);
            }
            if(ans != n)///必须要找到所有与之对应的才可以;
                printf("Case #%d: No
    ", t++);
            else
                printf("Case #%d: Yes
    ", t++);
        }
        return 0;
    }
    View Code
  • 相关阅读:
    7-22 朋友圈(25 分)
    c++之函数重载
    c++之函数的其它用法
    c++之引用
    c++之内存模型
    c++实例之通讯录管理系统之清空联系人功能(七)
    c++实例之通讯录管理系统之修改联系人功能(六)
    c++实例之通讯录管理系统之查找联系人功能(五)
    c++实例之通讯录管理系统之删除联系人功能(四)
    c++实例之通讯录管理系统之显示联系人功能(三)
  • 原文地址:https://www.cnblogs.com/zhengguiping--9876/p/6011534.html
Copyright © 2020-2023  润新知