hdu 5943 二分图+素数

来源:互联网 发布:淘宝促销文案范文 编辑:程序博客网 时间:2024/06/07 01:38

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

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

xmody=0xmody=0


Is there any way to satisfy everyone's requirement?
Input
First line contains an integer TT, which indicates the number of test cases. 

Every test case contains one line with two integers nnss

Limits 
1T1001≤T≤100
1n1091≤n≤109
0s1090≤s≤109.
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 yequals 'No'.
Sample Input
25 144 11
Sample Output
Case #1: NoCase #2: Yes

题意:有两组数(s+1,s+2,s+3,⋯,s+n)和(1,2,3,⋯,n);对左边的数按一定规律排序,是否可以是所有的数si%当前的位置i==0,si%i==0。

容易看出来是个二分图匹配的题,但是给的n和s的范围太大,不能直接用。

后来知道当【n+1,s+n】这个区间内存在两个素数时,可以直接输出no(因为在这个范围内的素数,只能选1这个位置)。而10^9以内的两个素数之间的差距最大不会超过300。所以可以直接判断当你>300时输出no。当n<=300时在用匈牙利算法做就可以。

有一个需要注意的地方:当n>s时两组数会有重复的地方,这个时候需要将重复的地方去掉,即交换n和s得值就可以。



#include<cstdio>#include<cstring>#include<iostream>using namespace std;int T,n,s,ans,line[500][500],used[500],vis[500];int dfs(int x){    for(int i=1;i<=n;i++){        if(!vis[i]&&line[x][i]){            vis[i]=1;            if(used[i]==-1||dfs(used[i])){                used[i]=x;                return 1;            }        }    }    return 0;}int main(){    scanf("%d",&T);    for(int Count=1;Count<=T;Count++){        scanf("%d%d",&n,&s);        if(n>s) swap(n,s);        if(n>300){            printf("Case #%d: No\n",Count);            continue;        }        memset(line,0,sizeof(line));        memset(used,-1,sizeof(used));        for(int i=1;i<=n;i++)            for(int j=1;j<=n;j++)                if((i+s)%j==0)                    line[i][j]=1;        ans=0;        for(int i=1;i<=n;i++){            memset(vis,0,sizeof(vis));            if(dfs(i))                ans++;        }        if(ans==n)            printf("Case #%d: Yes\n",Count);        else            printf("Case #%d: No\n",Count);    }    return 0;}