CF1916D Mathematical Problem
思路
很不错的人类智慧题。
拿到以后,完全没有思路,看到数据范围,感觉是什么
先打了个暴力程序,发现平方数太多,没什么规律,就拿了个 map 统计一下那些出现数字方案拥有的平方数比较多
程序如下:
#include<bits/stdc++.h>
using namespace std;
multiset<int>s;
map<multiset<int>,int>mp;
int main()
{
for(int i=1;i<=200000;++i)
{
long long k=1ll*i*i;
if(k<100000000) continue;//此程序是九位数的情况,想试其他情况的就改这里的值即可
if(k>999999999) break;
while(k) s.insert(k%10),k/=10;
++mp[s],s.clear();
}
for(auto i:mp)
{
if(i.second>=9)//这里也要改
{
for(auto j:i.first)
{
cout<<j<<" ";
}
puts("");
}
}
return 0;
}
先试一试五位数的情况,发现下面的数字组合都可以存在五个以上的平方数,除了样例给的还有一组。
- 0 0 1 6 9
- 1 3 4 6 8
再试一试七位数的情况,发现符合条件的数字组合更多了。
- 0 0 0 0 1 6 9
- 0 0 1 3 4 6 8
- 0 1 2 4 5 6 9
- 0 1 4 5 6 7 8
- 1 2 3 4 4 5 6
- 1 2 3 4 4 8 9
一看,发现了一个很重要的规律,都有
所以猜测所有情况都可以由若干个
再试一试九位数,发现也是如此。
于是,改了改暴力程序,让程序输出符合条件的平方数,如下:
#include<bits/stdc++.h>
using namespace std;
multiset<int>s;
map<multiset<int>,int>mp;
int main()
{
multiset<int>tmp;
tmp.insert(0),tmp.insert(0),tmp.insert(0),tmp.insert(0),tmp.insert(0),tmp.insert(0),tmp.insert(1),tmp.insert(6),tmp.insert(9);//同样是九位数的程序,其他情况注意更改参数
for(int i=1;i<=200000;++i)
{
long long k=1ll*i*i;
if(k<100000000) continue;
if(k>999999999) break;
while(k) s.insert(k%10),k/=10;
if(s==tmp) printf("%lld\n",1ll*i*i);
s.clear();
}
return 0;
}
先试一试五位数的,发现程序给的是:
10609
16900
19600
61009
90601
96100
研究了一下,发现首先又
剩下的就是
那么同理
使用暴力程序在七位数和九位数验证,发现是正确的。
再计算一下我们发现了多少个平方数了,在其中插入的零可以是
其实发现还有形如
根据上面发现的构造方案可以很轻松的写出程序。
AC code
#include<bits/stdc++.h>
using namespace std;
long long T,n,a,sum,num;
int main()
{
scanf("%lld",&T);
while(T--)
{
scanf("%lld",&n);
if(n==1){puts("1");continue;}//注意特判n=1
printf("169");
for(int i=4;i<=n;++i) printf("0");
puts("");
printf("961");
for(int i=4;i<=n;++i) printf("0");
puts("");
printf("196");
for(int i=4;i<=n;++i) printf("0");
puts("");
for(int i=1;i<n/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=3+2*i;j<n;++j) printf("0");
puts("");
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=3+2*i;j<n;++j) printf("0");
puts("");
}
}
return 0;
}