Goffi and Squary Partition
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 374 Accepted Submission(s): 145
Problem Description
Recently, Goffi is interested in squary partition of integers.
A set \(X\) of \(k\) distinct positive integers is called squary partition of \(n\) if and only if it satisfies the following conditions:
[ol]
A set \(X\) of \(k\) distinct positive integers is called squary partition of \(n\) if and only if it satisfies the following conditions:
[ol]
- the sum of \(k\) positive integers is equal to \(n\)
- one of the subsets of \(X\) containing \(k - 1\) numbers sums up to a square of integer.[/ol]
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 integers \(n\) and \(k\), whether there exists a squary partition of \(n\) to \(k\) distinct positive integers.
Input
Input contains multiple test cases (less than 10000). For each test case, there's one line containing two integers \(n\) and \(k\) (\(2 \le n \le 200000, 2 \le k \le 30\)).
Output
For each case, if there exists a squary partition of \(n\) to \(k\) distinct positive integers, output "YES" in a line. Otherwise, output "NO".
Sample Input
2 2 4 2 22 4
Sample Output
NO YES YES
Source
#include
#include
#include
#include
using namespace std;
int n,k;
int SQRT[450];
void init()
{
for(int i=0;i<450;i++)
SQRT[i]=i*i;
}
int fj[50];
int main()
{
init();
while(scanf("%d%d",&n,&k)!=EOF)
{
bool flag=false;
int ssum=(k-1)*(k-2)/2;
int R=(lower_bound(SQRT,SQRT+450,n)-SQRT-1);
int L=(upper_bound(SQRT,SQRT+450,ssum)-SQRT);
for(int x=R;x>=L;x--)
{
if(flag) break;
int sq=SQRT[x];
fj[k]=n-sq;
if(fj[k]<=0) break;
int sum=0,next=1;
for(int i=1;i<=k-2;i++)
{
if(next==fj[k]) next++;
fj[i]=next++;
sum+=fj[i];
}
fj[k-1]=n-fj[k]-sum;
if(fj[k-1]<=0)
{
continue;
}
if(fj[k-1]!=n-sq)
{
bool tf=true;
for(int i=1;i<=k-2;i++)
{
if(fj[k-1]==fj[i])
{
tf=false; break;
}
}
if(tf) flag=true;
}
else
{
if(k-2>=1)
{
fj[k-1]--;
fj[k-2]++;
if(fj[k-1]<=0) continue;
bool tf=true;
for(int i=1;i<=k-2;i++)
{
if(fj[k-1]==fj[i]||fj[k]==fj[i])
{
tf=false; break;
}
}
if(tf)
{
flag=true;
}
}
}
}
if(flag) puts("YES");
else puts("NO");
}
return 0;
}