Kingdom of ObsessionTime Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 2567 Accepted Submission(s): 757 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.
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.
Sample Input 2 5 14 4 11
Sample Output Case #1: No Case #2: Yes
|
题意:
给你一个n和s,问你能不能完成这样的操作:将s+1,s+2,s+3.....s+n进行排序,使得排序后,第一个可以整除1,第二个可以整除2....第n个可以整除n。
做法:
我们知道,素数只能被1整除,所以连续的区间之内最多只能有1个素数,但是又因为1e9的范围之内任意两个相邻素数之间的距离不会超过100,所以当数很大的时候我们可以直接筛去很多情况。剩下的只要暴力枚举每个数能与哪个相匹配,再连边跑一边匈牙利就好啦
代码如下:
#include<vector>
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
using namespace std;
const int inf=0x3f3f3f3f;
const int maxn=2505;
int obj[maxn],vis[maxn],n,s;
vector<int> ve[maxn];
int match(int x){
for(int i=0;i<ve[x].size();i++){
int v=ve[x][i];
if(!vis[v]){
vis[v]=1;
if(obj[v]==0||match(obj[v])){
obj[v]=x; return 1;
}
}
}
return 0;
}
void init(){
memset(obj,0,sizeof(obj));
for(int i=1;i<=2450;i++)
ve[i].clear();
}
int main(){
int t,cas=0;
cin>>t;
while(t--){
int now=0,flag=0;
scanf("%d%d",&n,&s);
init();
if(s<n) swap(s,n);
if(n>300) {
printf("Case #%d: No\n",++cas);
continue;
}
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++){
if((s+i)%j==0) ve[i].push_back(j);
}
}
int sum=0;
for(int i=1;i<=n;i++){
memset(vis,0,sizeof(vis));
if(match(i)) sum++;
}
if(sum==n) printf("Case #%d: Yes\n",++cas);
else printf("Case #%d: No\n",++cas);
}
return 0;
}