Good Bye 2023
D. Mathematical Problem
题目链接
题意:
给你一个奇数n,且 1 ≤ n ≤ 99 1\le n\le 99 1≤n≤99,让你输出n个长度为n的完全平方数,并且保证这n个完全平方数各个数位上数字组成的多重集完全一样。
思路:
最后一句说了数学家解决不了,问你能不能解决,所以纯数学证明是不可能了,这题是个构造。
一层考虑,因为因数乘10,那么平方后就相当于乘了100,那么对一个完全平方数,后面乘100,也一定是完全平方数。那么如果我们找到n+2个满足条件的n位数,就可以通过每个数都乘100得到n+2的一种解。因为n最大是99,所以我们如果可以找到99个满足条件(数位数字多重集相同)的k位数,那么就可以靠末尾填0得到所有n的情况,小于k的n直接打表,大于k的把上面的99个k位数打表,然后后面补0。
code:
#include <iostream>
#include <cstdio>
using namespace std;
typedef long long ll;
int T,n;
ll a[105]={0,10057482369,10208475369,10859307264,12938607504,13470852096,13985427600,14050783296,14809673025,15284376900,15309607824,15732684900,16203507849,16375809024,17049830625,17206093584,17345680209,17530289604,17689532004,18497360025,20134758609,20635897104,20851937604,20859736041,20897015364,21538497600,21753890064,23054170896,23081509476,24589376100,25083907641,25481736900,25713084609,25874009316,25930016784,25936780401,26913058704,27003691584,27058934016,27905368401,28391576004,28403709156,29754180036,30264517089,30410825769,30829741056,30902475681,31807652409,32059618704,32659718400,34900217856,35042716809,35047209681,35249687001,35600897124,35907218064,36108740529,36187452900,36805271409,37018529604,37019684025,37546812900,37984061025,38294576100,38417960025,38529764100,39207564081,40053217689,40305782169,40935810276,41273985600,41602537089,41753200896,43678910025,45038601729,45090823716,45231080976,45390728601,48621573009,48702310596,49370618025,50201987364,50704681329,51072836049,52381476900,52908740361,52987436100,53721968400,53968400721,54800937216,54807960321,54938672100,57408639201,58743216900,58932417600,59608734201,59736248100,60054893721,61538724900,62017435089};
//void p()
int main(){
cin>>T;
while(T--){
cin>>n;
switch(n){
case 1:printf("1\n");break;
case 3:printf("169\n196\n961\n");break;
case 5:printf("16384\n31684\n36481\n38416\n43681\n");break;
case 7:printf("1046529\n1695204\n1946025\n4052169\n5294601\n6215049\n9641025\n");break;
case 9:printf("254625849\n255296484\n256544289\n258952464\n289544256\n455224896\n562258944\n649485225\n946485225\n");break;
default:
for(int i=1;i<=n;i++){
cout<<a[i];
for(int j=12;j<=n;j++)
cout<<0;
puts("");
}
}
}
return 0;
}
第二层考虑,看 169 = 1 3 2 169=13^2 169=132这个数,可以发现在乘起来的过程中没有出现进位,也就是说如果我们在因数中间插入0,是不会影响乘出来对应位置上的数,对应位置上仍然是1,6,9,比如 10609 = 10 3 2 10609=103^2 10609=1032。同理 961 = 3 1 2 961=31^2 961=312也是。
所以我们可以在因数和积里插入0来构造满足条件的数,比如:
1006009=1003^2
1060900=1030^2
1690000=1300^2
9006001=3001^2
9060100=3010^2
9610000=3100^2
再加上一组特殊的:
1690000=1400^2
对169和961枚举中间插入的0的个数,各有 ( n − 3 ) / 2 + 1 (n-3)/2+1 (n−3)/2+1个,最后差一个,就拿169后面补0补上就行了。
正解code:
#include <iostream>
#include <cstdio>
using namespace std;
int T,n;
void print(int n){
for(int i=0;i<=(n-3)/2;i++){
printf("1");
for(int j=1;j<=i;j++)
printf("0");
printf("6");
for(int j=1;j<=i;j++)
printf("0");
printf("9");
for(int j=i*2+3+1;j<=n;j++)
printf("0");
puts("");
}
for(int i=0;i<=(n-3)/2;i++){
printf("9");
for(int j=1;j<=i;j++)
printf("0");
printf("6");
for(int j=1;j<=i;j++)
printf("0");
printf("1");
for(int j=i*2+3+1;j<=n;j++)
printf("0");
puts("");
}
cout<<"196";
for(int i=4;i<=n;i++)
printf("0");
puts("");
}
int main(){
cin>>T;
while(T--){
cin>>n;
if(n==1)puts("1");
else print(n);
}
return 0;
}