题目链接:http://bestcoder.hdu.edu.cn/contests/contest_showproblem.php?pid=1002&cid=530

(格式有一点点问题,直接粘下来吧)

题目意思:给出 n 和 k,问能否构造 k-1个不同的数使得这 k-1 个数(每个数都为正整数)的和等于一个数的平方,且 k 个数(都为正整数)的和等于 n。

错了差不多十多次,终于要看别人思路了.......

为了将问题简化,且保证 k-1 个数都是不同的,我们从自然数1,2,...,k-2 构造出前 k-2 个数,看清楚,不是 k-1 而是 k-2。因为最后第 k-1 个数有待斟酌!!!

设 square 为 k-1 个数之和,也就是等于的某个数的平方啦,remain 就是 n - square了。

先排除两种特殊情况:

(1) remain = 0 (不符合正整数的要求)或者 (k-1) * k /2 > square(因为是从1开始构造的,最小的square 都需要大于等于 (k-1)* k /2(1+2+3+...+k-1) ,避免无谓的计算

  (2)如果square = 1 并且 remain = 1 ,那么无解。这就是Sample 中的2 2了。

然后开始构造k-2个数。构造的时候,如果遇到remain(假如为x),就跳过一位,变成x+1,使得构造的数中不包含remain。因此代码中就有 x 多自增1次的操作了。

构造完 k-2 个数之后(设和为sum),我们要对最后一个数,即第 k-1个数进行讨论(代码中的need,它的值等于 n - sum - remain)。如果这个 need <= x (第 k-2 个数的值就是x),代表 k - 1个数中有两个数是相同的,与题意不符。而且它就算怎样调整都不能构造出答案,因为我们是从最小的自然数1开始构造的!

比较难理解的是,最后的那个k-1的数,我们还是x++,但是sum + x 有可能并不等于 (确切来讲是小于,如果是大于都是无解的,从最小数开始构造嘛)square,但是我们可以调整 k-2个数中的某个数ai令它大点--->ai+k,使得sum + x(此时的x不是原来单纯的 x++ 了,x = square-(sum-ai+ai+k)) 不过这些情况比较复杂,所以我们反其道而行之,讨论无解的情况!

无解的时候,有两种情况。最后 前面不是说 x++ 吗,那么第一种肯定无解的情况:x == remain && need == remain!这个表示remain 在k-2个数的构造中根本没有遇到。而且need这个值 是必须的,无论前面怎样调整,还是那个道理,从最小数1开始构造。

最难理解的是第二种情况 x+1 == remain && need == remain (我也想了好久才想通,wa了这么多次就是这个没想出来)。remain 是动不了的,只能从need 和 前面已经构造了的 k-2个数中开刀。

我们不希望need = remain,于是只能让k-2个数中的某个数增加1(确切来讲只能是黑色字体的x,因为数与数之间是紧挨着的),变成蓝色部分的x++,此时need 确实不等于 remain,但是need 却等于蓝色部分的x++(need - 1)了,也就是最后构造出来的k-1 个数中有两个数是相同的!!!

只要排除这两种情况,就表示可以得出解。

 #include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
using namespace std; int n, k; bool check(int square, int remain)
{
if (remain == && square == ) // k = 2, remain = 1的情况
return false;
int sum = ;
int x = ;
for (int i = ; i < k-; i++) // 构造k-2个数
{
x++;
if (x == remain)
x++;
sum += x;
}
int need = n-sum-remain;
if (need <= x) // 最后第k-1个数在前k-2个已构造数里面
return false;
// need > x(未自增前),有可能与remain有冲突(remain在k-2个数之外)
x++;
if (x == remain || x + == remain)
{
if (need == remain) // need == remain == x
return false; // or need == remain == x+1
}
return true; // need > x+1
} int main()
{
while (scanf("%d%d", &n, &k) != EOF)
{
int flag = ;
for (int i = ; i * i < n && !flag; i++)
{
int square = i*i;
int remain = n - square;
if (remain == || (k-)*k/ > square)
continue;
if (check(square, remain))
{
flag = ;
break;
}
}
printf("%s\n", flag ? "YES" : "NO");
}
return ;
}

BestCoder6 1002 Goffi and Squary Partition(hdu 4982) 解题报告的更多相关文章

  1. BestCoder22 1002.NPY and arithmetic progression(hdu 5143) 解题报告

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5143 题目意思:给出 1, 2, 3, 4 的数量,分别为a1, a2, a3, a4,问是否在每个数 ...

  2. BestCoder16 1002.Revenge of LIS II(hdu 5087) 解题报告

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5087 题目意思:找出第二个最长递增子序列,输出长度.就是说,假如序列为 1 1 2,第二长递增子序列是 ...

  3. HDU 4982 Goffi and Squary Partition(推理)

    HDU 4982 Goffi and Squary Partition 思路:直接从全然平方数往下找,然后推断是否能构造出该全然平方数,假设能够就是yes,假设都不行就是no.注意构造时候的推断,因为 ...

  4. hdu 4982 Goffi and Squary Partition

    Goffi and Squary Partition Time Limit: / MS (Java/Others) Memory Limit: / K (Java/Others) Total Subm ...

  5. hdu4982 Goffi and Squary Partition (DFS解法)

    BestCoder Round #6 B http://acm.hdu.edu.cn/showproblem.php?pid=4982 Goffi and Squary Partition Time ...

  6. 【HDOJ】4982 Goffi and Squary Partition

    题意就是整数划分,选出和为n的K个整数,其中K-1个数的和为完全平方数S.选择整数时需要从1,2,3..连续选择,当选择整数与n-S相等时,需要跳过n-S,即选择n-S+1.如此选择K-2个数,从而可 ...

  7. Goffi and Squary Partition

    题意: 给你N和K,问能否将N拆分成K个互不相同的正整数,并且其中K-1个数的和为完全平方数. PS:这道题目原来是要求输出一种可行方案的,所以下面题解是按照输出方案的思想搞的. 分析: 我们尝试枚举 ...

  8. BestCoder20 1002.lines (hdu 5124) 解题报告

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5124 题目意思:给出 n 条线段,每条线段用两个整数描述,对于第 i 条线段:xi,yi 表示该条线段 ...

  9. BestCoder18 1002.Math Problem(hdu 5105) 解题报告

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5105 题目意思:给出一个6个实数:a, b, c, d, l, r.通过在[l, r]中取数 x,使得 ...

随机推荐

  1. C# MD5加密(16进制)

    MD5加密(16进制) vs会提示引用 using System.Security.Cryptography; 代码如下: public static string MD5Encrypt32(stri ...

  2. Office 各版本下载链接

    Office 2007 链接: https://pan.baidu.com/s/1pNJDlafw6KQSlljRUAQtWw 提取码: xoml 密钥:DBXYD-TF477-46YM4-W74MH ...

  3. PyTorch学习笔记之Tensors 2

    Tensors的一些应用 ''' Tensors和numpy中的ndarrays较为相似, 因此Tensor也能够使用GPU来加速运算 ''' # from _future_ import print ...

  4. Ubuntu 16.04下使用Wine安装Windows版的微信(不太完美)

    说明: 真的不太完美,别试了:除了需要安装额外的输入法之后,无法上传图片和间接性的BUG出现等等问题. 建议安装网页版的微信:http://www.cnblogs.com/EasonJim/p/711 ...

  5. TIdHTTPServer制作REST中间件

    TIdHTTPServer制作REST中间件 使用DELPHI7+INDY9开发 // 陈新光 2017-2-21// LIS数据同步服务器// 浏览器输入:http://127.0.0.1:8000 ...

  6. SilverLight-DataControls:四、The PagedCollectionView(分页的集合视图) 对象

    ylbtech-SilverLight-DataControls-PagedCollectionView:The PagedCollectionView(分页的集合视图) 对象 1.A, Buildi ...

  7. mycat安装和测试

    mycat安装和测试 一.  环境准备 本机环境是三台centos6.5 IP 主机名 数据库名 安装软件 192.168.17.4 master db1 mycat,mysql 192.168.17 ...

  8. margin: 0 auto; 元素水平居中布局无效

    失效原因: 要给居中的元素一个宽度,否则无效. 该元素一定不能浮动或绝对定位,否则无效. 在HTML中使用<center></center>标签,需考虑好整体构架,否者全部元素 ...

  9. ThinkPHP学习(五)图片验证码

    今天用到图片验证码的功能,在网上找到ThinkPHP的下面代码: Public function verify(){ import('think.Image'); Image::buildImageV ...

  10. sql 表的部分字段查找 的结果集

    传统sql从多个对象中获得的list<Object> ,可以这样处理(利用Map)  List list = query.getList(sql);  //封装成BB类型  List< ...