是前天比赛的第一题,觉得蛮有意思的,在这里提一下。
首先我们知道打表是肯定可以过的==只是judge上交不了那么长的代码==
Description
定义S(x)为x每位上的数字和。
如果S(x∗x)=S(x)∗S(x)
则称x为
求
Solution
打表中我们可以发现一些规律
比如每一位最大是3
我们来证明这个结论。
首先我们证明二位数的结论
首先
S(ab¯¯¯2)=S(100a2+b2+20ab)<=a2+b2+2ab=S2(ab¯¯¯)
观察式子发现只要有进位等号就不成立。
那么a2<=10,,b2<=10,2ab<=10
=>a<=3,b<=3 同时相邻两位乘积<=5
又S(ab¯¯¯2)<=162
=>S(ab¯¯¯)<=12
然后就可以爆搜了
[源代码]
#include<iostream>
#include<algorithm>
#include<string.h>
#include<stdio.h>
using namespace std;
typedef long long ll;
inline int S(ll x){
int res=0;
for(;x;)res+=x%10,x/=10;
return res;
}
int ed[10],cnt,n,l,r;
inline void pret(){
for(int i=0;i<=3;++i)
ed[i]=min(3,4-i);
}
inline void dfs(int v,int last,int sum,int s){
if(sum>r||s>12)return;
if(v==n+1){
if(sum<l)return;
if(s*s==S(1ll*sum*sum))++cnt;
return;
}
for(int i=0;i<=ed[last];++i)
dfs(v+1,i,sum*10+i,s+i);
}
int main(){
cin>>l>>r;
pret();
for(int sw=r;sw;)sw/=10,++n;
dfs(1,0,0,0);
printf("%d\n",cnt);
return 0;
}
三优代码哈哈哈