Kingdom of Obsession
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 0 Accepted Submission(s): 0
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
Is there any way to satisfy everyone's requirement?
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 n , s .
Limits
1≤T≤100 .
1≤n≤109 .
0≤s≤109 .
Every test case contains one line with two integers n , s .
Limits
1≤T≤100 .
1≤n≤109 .
0≤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 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个人,id序号分别为是s+1到s+n,他们各自想站在第i个位置(id%i==0),问全部人能否站在想要的位置上。
思路:一看就是二分图,但数据很大不可能一一建边,然后想到了只要id里存在两个素数就不可能匹配成功,然后大概估算一下每1000个肯定有两个素数吧。然后就是暴力n^2建边,跑一遍二分图就好了。这里有个问题,区间重叠,如果重叠的话就算存在两个素数也是可以匹配了,因为可以一一对应。所以这里要特殊处理一下,区间重叠的部分默认匹配成功,剩下的部分跑二分图就好了,一开始这里没想到,一直wa。。下面给代码:
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
#include<cmath>
#include<queue>
#include<utility>
#include<map>
#define maxn 2005
#define inf 0x3f3f3f3f
typedef long long LL;
using namespace std;
const int mod = 1e9 + 7;
int head[maxn], vis[maxn];
bool book[maxn];
struct node{
int v, next;
}p[maxn*maxn];
bool find(int x)
{
for (int i = head[x]; ~i; i = p[i].next)
{
int y = p[i].v;
if (!book[y])//防止同一个人被搜两次 ,不然会死循环
{
book[y] = true;
if (!vis[y] || find(vis[y]))//没人占用或者占用你的人可以找到新欢,太好了
{
vis[y] = x;
return true;
}
}
}
return false;
}
int main(){
int t;
scanf("%d", &t);
for (int tcase = 1; tcase <= t; tcase++){
memset(head, -1, sizeof(head));
memset(vis, 0, sizeof(vis));
int n, s, len = 0;
scanf("%d%d", &n, &s);
if (s + 1 <= n)
swap(n, s);
if (n > 1000)
printf("Case #%d: No\n", tcase);
else{
for (int i = s + 1; i <= s + n; i++){
for (int j = 1; j <= n; j++){
if (i%j)
continue;
int u = i - s + 1000;
p[len].v = j;
p[len].next = head[u];
head[u] = len++;
p[len].v = u;
p[len].next = head[j];
head[j] = len++;
}
}
int ans = 0;
for (int i = 1; i <= n; i++)
{
memset(book, false, sizeof(book));//用来标记配偶是否被搜过一次
if (find(i))ans++;//找到配偶啦!好开心。对数++
}
if (ans == n)
printf("Case #%d: Yes\n", tcase);
else
printf("Case #%d: No\n", tcase);
}
}
}