K - Kingdom of Obsession 二分图+思维 CCPC

链接:https://vjudge.net/contest/364924#problem/K

题意:给出n跟s,让我们将(s+1,s+n)范围内的数找一个可能的次序让其满足每一个位置的数mod位置==0

   即:val%pos==0

思路:首先我们可以想到的是二分图匹配解法,但是数据范围太大,操作不了

不过我们知道素数有个特性就是因数只有1和它本身。所以素数只能待在位置1或者标号为本身的位置上

1.如果m>n

在这种情况下,只要在(m+1,m+n)有一个素数,都是不可能匹配的。所以我们要算出两个素质之间的最大距离

如果n大于等于两个素数之间的距离,那么肯定是不可能匹配的。

如果小于直接二分图匹配一下。

2.如果m<=n

 

 

 有一部分重合的地方,这部分的值跟位置相等,即满足mod==0的情况,这个时候就直接算后面的那部分即可(n,n+m)

在这种情况下,重合部分用掉的pos为(m,n),即剩下可用的pos为(1,m)所以可以直接用一个swap操作代替这一过程

 

 

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 const int maxn=1e4+10;
 4 int vis[maxn];
 5 int n,s;
 6 struct node
 7 {
 8     int v,nxt;
 9 }G[maxn];
10 int num;int head[maxn];
11 int now[maxn];
12 void add(int u,int v)
13 {
14     G[++num].v=v;G[num].nxt=head[u];head[u]=num;
15 }
16 int match(int u)
17 {
18     for(int i=head[u];i;i=G[i].nxt){
19         int v=G[i].v;
20         if(!vis[v]){
21             vis[v]=1;
22             if(!now[v]||match(now[v])){
23                 now[v]=u;
24                 return 1;
25             }
26         }
27     }
28     return 0;
29 }
30 void init()
31 {
32     memset(head,0,sizeof(head));
33     memset(now,0,sizeof(now));
34     num=0;
35 }
36 int main()
37 {
38     int T;
39     scanf("%d",&T);
40     int Case=0;
41     while(T--){
42         init();
43         scanf("%d%d",&n,&s);
44         if(s<n) swap(s,n);
45         if(n>300){
46             printf("Case #%d: No\n",++Case);
47             continue;
48         }
49         for(int i=1;i<=n;i++){
50             for(int j=1;j<=n;j++){
51                 if((i+s)%j==0) add(i,j);
52             }
53         }
54         int ans=0;
55         for(int i=1;i<=n;i++){
56             memset(vis,0,sizeof(vis));
57             if(match(i)) ans++;
58         }
59         if(ans==n) printf("Case #%d: Yes\n",++Case);
60         else printf("Case #%d: No\n",++Case);
61     }
62     return 0;
63 }
View Code

 

posted @ 2020-10-08 16:55  古比  阅读(180)  评论(0编辑  收藏  举报