首页 > 代码库 > [BestCoder Round #6] hdu 4982 Goffi and Squary Partition(构造)
[BestCoder Round #6] hdu 4982 Goffi and Squary Partition(构造)
Goffi and Squary Partition
Problem Description
Recently, Goffi is interested in squary partition of integers.
A setX ofk distinct positive integers is called squary partition ofn if and only if it satisfies the following conditions:
- the sum of
k positive integers is equal ton - one of the subsets of
X containingk?1 numbers sums up to a square of integer.
For example, a set {1, 5, 6, 10} is a squary partition of 22 because 1 + 5 + 6 + 10 = 22 and 1 + 5 + 10 = 16 = 4 × 4.
Goffi wants to know, for some integersn andk , whether there exists a squary partition ofn tok distinct positive integers.
Input
Input contains multiple test cases (less than 10000). For each test case, there‘s one line containing two integersn andk (2≤n≤200000,2≤k≤30 ).
Output
For each case, if there exists a squary partition ofn tok distinct positive integers, output "YES" in a line. Otherwise, output "NO".
Sample Input
2 2 4 2 22 4
Sample Output
NO YES YES
给出n,k,问能不能把n拆成k个不同的正整数相加,且其中k-1个数的和为完全平方数。
比如 n=22 ,k =4, 22可以拆成 1+5+6+10,且 1+5+10=4*4
BESTCODER主页上的题解:
PS:这道题目原来是要求输出一种可行方案的,所以下面题解是按照输出方案的思想搞的。 分析: 我们尝试枚举那个完全平方数 S,然后看能否将他拆分为 K-1 个数,并且不用到N-S 这一步可以用贪心+一次调整来搞定。为了保证 K-1 个数都不同,我们尝试尽量用 1,2,3...这些连续自然数来构造,如果 N-S 出现在这些数中,那么将 N-S 移除,再新加一个数。如果这样都不能拆分成 K-1 个数,那么这个 S 肯定不行。 现在考虑已经用上述方法拆分了,我们需要判断这个拆分是否可行。会产生问题的只有最后一个数,这个数可能和 N-S 一样,也可能出现在之前的序列。如果是出现在之前的序列,那么这个拆分也是不靠谱的。如果和 N-S 一样,那么分两种情况 1. N-S 曾出现在之前的序列,那么显然这个拆分也是不靠谱的 2. N-S 比倒数第二个数大,对于这种我们可以通过调整最后一个数和倒数第二个数的大小,来使得这个拆分成立,假设最后一个数为 a,倒数第二个为 b,只要 a-1,b+1 就好了。当然如果 a-1 = b+1 这个拆分也是不靠谱的这道题目就这样搞定了,其实没必要找所有的完全平方数,只要找小于 N 与 N 最接近的完全平方数就好了。枚举出一个完全平方数,那么剩下的数就确定了,下面就开始判断剩下的那个数是否符合题意。
构造出完全平方数的k-1个数,从小到大,贪心,1,2,3.....
#include <iostream> #include <cmath> #include <stdio.h> using namespace std; int n,k; bool judge(int s)//s为枚举出来的完全平方数 { int f=n-s;//剩下的 int t=1;//t为构造出来的数 for(int i=1;i<=k-2;i++)//开始构造k-1个数中的前k-2个,剩下的那个数为s { if(t==f) t++; s-=t; if(s<=t) return false; t++; } t--; //到此为止,t为构造出的k-1个数中的倒数第二个,s为倒数第一个 while(1) { if(s<=t)//最后一个数出现在前面的序列中 return false; if(s!=f) return true; //s==f时,调整s,t s--; t++; //s+t和不变。 } } bool ok() { int m=(int)sqrt(n); if(m*m==n)//枚举时要求完全平方数<n才可以 m--; while(m) { if(judge(m*m)) return true; m--; } return false; } int main() { while(scanf("%d%d",&n,&k)==2) { if(ok()) printf("YES\n"); else printf("NO\n"); } return 0; }
[BestCoder Round #6] hdu 4982 Goffi and Squary Partition(构造)
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。