2021-3-27 广工校赛 C题-涂墙 解题报告
题目描述
母牛哥有一桶油漆,把它用完可以给n平方米的墙涂上颜色.
母牛哥想要在墙上涂5个正方形(这些正方形的边长都是整数,单位是米),并且刚好把油漆用完.
母牛哥能做到吗?
输入描述
第一行一个数字t(<=1000),表示测试样例数量
接下来t行,每行一个数字n(0<=n<=1000000),表示母牛哥的油漆可以涂多少平方米.
输出描述
输出t行,对于每个输入.
如果母牛哥能够做到,就输出YES.
否则输出NO.
解题所需预备知识
1.拉格朗日四平方数和定理:任意一个非负整数可以表示为四个平方数的和
2.有一个特殊的数字169可以分别表示成1,2,3,4,5个正平方数的和
169=13^2
169=122+52
169=122+44+3^3
169=102+82+22+12
169=122+42+22+22+1^1
解题思路
所以对于任意大于169的数都可以用 n=169+m表示
而m可以表示为四个平方数的和
所以当m分解出4个平方数时,n=m(4)+13^2
所以当m分解出3个平方数时,n=m(3)+122+52
所以当m分解出2个平方数时, n=m(2)+122+44+3^3
所以当m分解出1个平方数时, n=m(1)+102+82+22+12
所以n>=169的所有数字都能用5个平方数表示
而n<169时我们可以用暴力打表,把不满足的情况找到,打表代码如下
#include<stdio.h>
int main()
{
int sum,flag;
for(int n=169;n>0;n--)
{
int i=1,j=1,k=1,l=1,m=1;
flag=0;
for(i;i<=12;i++)
{
j=1;
for(j;j<=12;j++)
{
k=1;
for(k;k<=12;k++)
{
l=1;
for(l;l<=12;l++)
{
m=1;
for(m;m<=12;m++)
{
sum=i*i+j*j+k*k+l*l+m*m;
if(n==sum)
{
flag=1;
printf("%d ",n);
break;
}
}
if(flag)
break;
}
if(flag)
break;
}
if(flag)
break;
}
if(flag)
break;
}
}
return 0;
}
所以最终答案如下
#include<stdio.h>
int main()
{
int a[]={0,1,2,3,4,6,7,9,10,12,15,18,33};
int t,n,flag;
scanf("%d",&t);
while(t--)
{
flag=1;
scanf("%d",&n);
for(int i=0;i<13;i++)
{
if(n==a[i])
{
flag=0;
printf("NO\n");
break;
}
}
if(flag)
printf("YES\n");
}
return 0;
}
参考https://blog.nowcoder.net/n/23c39776b3554c2289106c0cfd0d70e8?f=comment