HDU5943 题解

题意

个数 ,求是否能将这 个数放到 上,且当令原数为 ,放到 位置时有

不超过 组数据,

题解

看上去很吓人的数据范围,也是一个让你以为这是结论题的数据范围。

但是仔细观察可以发现,当 中有 个及以上质数时,只有将他们安排到 位置或者质数自身位置才有

首先尝试将这两个质数安排到其自身的位置,这要求 ,即要求

那么此时 就能够安排到自己的位置了,那么就只剩下 了,可以发现这就是 交换后的结果。

但是,当 交换后,或者 不能交换时,存在 个或以上质数,那么显然无解了。另外,根据结论,在 范围内,大约 个数就会出现一次质数,这里保险起见设 个数出现一次质数。

这里又有一个很神奇的问题,ans+=can[i] 前面不能加 if(!match[i]),具体原因未知。

代码

#include<cstdio>
#include<algorithm>
#include<cstring>
const int MAXN=2000+5;
int n,s,match[MAXN],ver,vis[MAXN];
bool can(int x)
{
    vis[x]=ver;
    for(int i=1;i<=n;i++)
        if((s+x)%i==0 && (!match[i]||(vis[match[i]]!=ver&&can(match[i]))))
        {
            match[i]=x;
            return 1;
        }
    return 0;
}
int main()
{
    int T;
    scanf("%d",&T);
    for(int t=1;t<=T;t++)
    {
        memset(vis,0,sizeof(vis));
        memset(match,0,sizeof(match));
        scanf("%d %d",&n,&s);
        if(s<n) std::swap(n,s);
        if(n>1000)
        {
            printf("Case #%d: No\n",t);
            continue;
        }
        int ans=0;
        for(int i=1;i<=n;i++)
        {
            ver=i;
            ans+=can(i);
        }
        printf("Case #%d: %s\n",t,ans==n?"Yes":"No");
    }
    return 0;
}
全部评论

相关推荐

评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务