Hdu 5943 Kingdom of Obsession【素数+二分匹配】

来源:互联网 发布:ubuntu输入法怎么用 编辑:程序博客网 时间:2024/06/02 18:32

Kingdom of Obsession

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 1450    Accepted Submission(s): 433


Problem Description
There is a kindom of obsession, so people in this kingdom do things very strictly.

They name themselves in integer, and there are n people with their id continuous (s+1,s+2,,s+n) standing in a line in arbitrary order, be more obsessively, people with id x wants to stand at yth position which satisfy

xmody=0


Is there any way to satisfy everyone's requirement?
 

Input
First line contains an integer T, which indicates the number of test cases.

Every test case contains one line with two integers ns.

Limits
1T100.
1n109.
0s109.
 

Output
For every test case, you should output 'Case #x: y', where x indicates the case number and counts from 1 and y is the result string.

If there is any way to satisfy everyone's requirement, y equals 'Yes', otherwise y equals 'No'.
 

Sample Input
25 144 11
 

Sample Output
Case #1: NoCase #2: Yes
 

Source
2016年中国大学生程序设计竞赛(杭州)

题目大意:


给出1~N,N个位子,然后给出s+1~s+N,N个数,一个数x可以放在位子pos的条件是:x%pos==0,问我们这N个数能否放在N个位子上。


思路:


问题可以分成两种情况去讨论:


①s<=n,我们知道,此时这种情况,我们肯定希望从s+1到n这些数,都放在位子s+1到n上是最好的,然后我们去判定从n+1到n+s这些数,能否放在从1到s这些位子上即可。

但是我们知道,如果这里s很小的话,我们可以进行二分图匈牙利匹配即可,否则如果s很大的话我们没法搞定这个问题。

随后观察到问题的本质,我们如果从n+1到s+n有一个素数的话,这个素数无论如何都要放在位子1上才行,如果有两个素数的话,问题的结果肯定就是No了。根据素数间隔的一些理论我们知道,大约一个素数和另一个素数的间隔,在int范围内的话,大概有300+个数就会再出现另一个素数,所以我们可以判定,如果s大于了1000的话,就一定是No的结果了。

从而搞定了当前情况的解。


②s>n,其实这种情况,我们交换一下s和n,问题就翻转变成了①的问题,而且对结果并没有影响。


Ac代码:

#include<stdio.h>#include<string.h>#include<vector>using namespace std;vector<int>mp[1500];int match[1500];int vis[1500];int find(int u){    for(int i=0;i<mp[u].size();i++)    {        int v=mp[u][i];        if(vis[v]==0)        {            vis[v]=1;            if(match[v]==-1||find(match[v]))            {                match[v]=u;                return 1;            }        }    }    return 0;}int main(){    int t;    int kase=0;    scanf("%d",&t);    while(t--)    {        int n,s;        scanf("%d%d",&n,&s);        if(s>n)swap(n,s);        printf("Case #%d: ",++kase);        if(s>=1400)printf("No\n");        else        {            for(int i=1;i<=s;i++)            {                mp[i].clear();                for(int j=n+1;j<=s+n;j++)                {                    if(j%i==0)                    {                        mp[i].push_back(j-n);                    }                }            }            int output=0;            memset(match,-1,sizeof(match));            for(int i=1;i<=s;i++)            {                memset(vis,0,sizeof(vis));                if(find(i))output++;            }            if(output==s)printf("Yes\n");            else printf("No\n");        }    }}










阅读全文
0 0
原创粉丝点击