链接:http://acm.hdu.edu.cn/showproblem.php?pid=5943
题意:两个区间,一个1-n 一个 s+1----s+n 问 s重新排列放在第一个里面,使得所有 si%(kth)==0。。。叙述不清楚大家可以看原题
思路:一眼看去不可做。。大概猜一猜如果范围小就是一个二分图匹配嘛。。。又因为素数分布确实是很近的(具体有各种各种猜想。)。。所以直接莽,
但是!!。。。重现赛时候忘记处理一种情况了。。就是区间重叠的时候。。因为之前为什么可以特判区间大就无法匹配了,因为有两个以上素数肯定没法匹配(素数只 能和1匹配。。)但是区间相交就可以和自己匹配了。。所以怎么办呢。。其实就是抹掉相交区间就可以了。。(重现赛的时候因为这个低级错误一直WA。。。一下来就 小黄鸭调试法了?)
代码:
#include <bits/stdc++.h>
using namespace std;
int n,s;
const int MAXN = 1000;
int uN,vN;//u,v的数目,使用前面必须赋值
int g[MAXN][MAXN];//邻接矩阵
int linker[MAXN];
bool used[MAXN];
bool dfs(int u){
for(int v = 0; v < vN; v++)
if(g[u][v] && !used[v]){
used[v] = true;
if(linker[v] == -1 || dfs(linker[v]))
{
linker[v] = u;
return true;
}
}
return false;
}
int hungary(){
int res = 0;
memset(linker,-1,sizeof(linker));
for(int u = 0; u < uN; u++){
memset(used,false,sizeof(used));
if(dfs(u))res++;
}
return res;
}
int main(){
int t,ca=1;
scanf("%d",&t);
while(t--){
scanf("%d%d",&n,&s);
if(s<n)swap(n,s);
if(n>500){
printf("Case #%d: No
",ca++);
}
else{
memset(g,0,sizeof(g));
for(int i=s+1;i<=s+n;i++){
for(int j=1;j<=n;j++){
if(i%j==0){
g[j-1][i-s-1]=1;
}
}
}
uN=n,vN=n;
if(hungary()==n){
printf("Case #%d: Yes
",ca++);
}
else{
printf("Case #%d: No
",ca++);
}
}
}
}