Kingdom of Obsession
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 1202 Accepted Submission(s): 368
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
y
th![]()
position which satisfy
Is there any way to satisfy everyone's requirement?
They name themselves in integer, and there are n
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 n
,
s
.
Limits
1≤T≤100
.
1≤n≤10
9![]()
.
0≤s≤10
9![]()
.
Every test case contains one line with two integers n
Limits
1≤T≤100
1≤n≤10
0≤s≤10
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'.
If there is any way to satisfy everyone's requirement, y equals 'Yes', otherwise y equals 'No'.
Sample Input
2 5 14 4 11
Sample Output
Case #1: No Case #2: Yes
题解:数学+二分图匹配
打表可知:n和s存在对称关系,即n和s互换对答案没有影响根据这一点,可以使n小于s。这样有什么用呢?
我们知道素数的约数只有1和本身,我们令n<s后,编号的区间为[s+1,s+n]
因此只要再区间[s+1,s+n]中有2个素数,那么这种情况肯定是No(因为[1,n]中只有一是这些素数的约数)再根据10E以内相邻素数之差不会超过300,因此只要n>300即输出No
当n在300以内时,就可以用二分图匹配将编号和其约数配对,如果匹配成功则输出Yes
#include<bits/stdc++.h>
using namespace std;
const int MX = 2e3 + 5;
struct Edge{
int v,nxt;
}E[MX*MX];
int head[MX],tot;
void init(){
memset(head,-1,sizeof(head));
tot=0;
}
void add(int u,int v){
E[tot].v=v;
E[tot].nxt=head[u];
head[u]=tot++;
}
int match[MX];
bool vis[MX];
bool DFS(int u) {
for(int i = head[u]; ~i; i = E[i].nxt) {
int v = E[i].v;
if(!vis[v]) {
vis[v] = 1;
if(match[v] == -1 || DFS(match[v])) {
match[v] = u;
return 1;
}
}
}
return 0;
}
int BM(int n) {
int res = 0;
memset(match, -1, sizeof(match));
for(int u = 1; u <= n; u++) {
memset(vis, 0, sizeof(vis));
if(DFS(u)) res++;
}
return res;
}
int main(){
int T,n,s;
scanf("%d",&T);
for(int cas=1;cas<=T;cas++){
printf("Case #%d: ",cas);
scanf("%d%d",&n,&s);
if(n>s) swap(n,s);
if(n>600) {
printf("No\n");
continue;
}
init();
for(int i=s+1;i<=s+n;i++){
for(int j=1;j<=n;j++){
if(i%j==0) {
add(i-s+n,j);
add(j,i-s+n);
}
}
}
if(BM(2*n)==2*n) printf("Yes\n");
else printf("No\n");
}
return 0;
}