hdu 5943 素数分布+二分图匹配

链接: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\n",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\n",ca++);
            }
            else{
                 printf("Case #%d: No\n",ca++);
            }
        }
    }
}




posted @ 2016-10-29 18:48  zhangxianlong  阅读(131)  评论(0编辑  收藏  举报