首页 > 代码库 > HDU 4982 Goffi and Squary Partition(BestCoder Round #6 1002)

HDU 4982 Goffi and Squary Partition(BestCoder Round #6 1002)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4982


解析:

   题意:
        给你N和K,问能否将N拆分成K个互不相同的正整数,并且其中K-1个数的和为完全平方数


    实际上,一拿到题目,我先想了下这里会不会存在负数或者0,后来经过几次华丽丽的WA之后发现,这题确实不用考虑到非正数。但是还是想吐槽一下,这个题目的意思也有点儿太不明晰了。。。

    再说回题目来,我们枚举所有的完全平方数i*i,然后看能否将他拆成k-1个数,并且用不到n-i*i。所以这里我们用到贪心+部分特殊处理。

    我们尝试尽量用 1,2,3...这些连续自然数来构造,如果 n-i*i 出现在这些数中,那么将 n-i*i 移除,再新加一个数。如果这样都不能拆分成 k-1 个数,那么这个完全平方数( i*i) 肯定不行。

    由于我们不需要输出某一个具体答案,所以也就不需要dfs那么高深费劲的解法了,在这里我们只需要找到一个可能性就可以直接跳出循环了。


   找到可能性的等价事件就是排除所以不可能的事件。

    那么我们看看有哪些不可能构造的情况吧!

    1.前k-1个数的和就已经超过n,那可定就不可能用k个数字来表示n了;

    2.在举例每个完全平方数的时候:

        2.1 前k-1个数的和大于完全平方数;

        2.2 n-i*i在前k-1个数里面,那么必然构造完全平方数的时候不会用到n-i*i而最小要用到数字k,然而前k个 数之和减去n-i*i大于完全平方数(i*i);

        2.3 如果n-i*i==k,并且前k-1个数之和加上1等于完全平方数,那么后者必然也会用到k,所以这种情况也不成立。(当然前k-1个数之和加上t(t>1)等于完全平方数,就可以不必用到数字k,其他的情况也是如此)


代码:

/*
ID:muller8
Name: 4982 Goffi and Squary Partition
Reference: 贪心
*/

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <algorithm>
#include <vector>
#include <cmath>
using namespace std;
#define MAXN 10005
#define INF 1e9

int main(){
    int n,k;
    while(~scanf("%d%d", &n, &k)){
        bool flag;
        if((k+1)*k/2>n) flag = false;
        else{
            int i;
            flag = false;
            for(i=1; i*i<n; ++i){
                int left = n-i*i;
                if(k*(k-1)/2>i*i)   continue;
                if((left<=k-1)&&(k*(k+1)/2-left>i*i)) continue;
                if(left==k&&k*(k-1)/2+1==i*i)   continue;
                flag = true;
                break;
            }
        }
        printf("%s\n", flag?"YES":"NO");
    }
    return 0;
}


HDU 4982 Goffi and Squary Partition(BestCoder Round #6 1002)