問題はこちら
No.537 ユーザーID - yukicoder
2つの数A,Bを連結するのは、文字列として処理するのでも良いが、Cだと面倒なので計算をする
数Bの桁数はで得られるので、AとBをこの順で連結したものはで求められる
Nが大きいので1~√Nまでを調べる
long n,s[20000],k,i,t,A;
c(long*a,long*b){return *a<*b?1:*a>*b?-1:0;}
main(){
scanf("%ld",&n);
for(i=1;i*i<=n;i++)if(n%i==0){
s[k++]=n/i*pow(10,t=log10(i)+1)+i;
s[k++]=i*pow(10,t=log10(n/i)+1)+n/i;
}
qsort(s,k,8,c);
for(;k--;)A+=s[k]!=s[k+1];
printf("%d",A);
}
OEISによれば10^12以下の数は高々6720個の約数しか持たないので、「既出の数かどうか」は毎回チェックしても間に合う
また、iがnの約数なら、「iをn/iと取り替える」という操作を2度行うとiはもとの値に戻るので、これを利用して、前後の入れ替えを1つにまとめられる
long n,s[9999],k,i,j,t,x;
main(){
scanf("%ld",&n);
for(i=1;i*i<=n;i++)if(n%i==0){
for(x=0;x<2;x++){
t=n/i*pow(10,t=log10(i)+1)+i;
for(j=0;j<k;j++)if(s[j]==t)break;
if(j==k)s[k++]=t;
i=n/i;
}
}
printf("%d",k);
}
3重for文をいい感じにまとめる。
特に工夫せずとりあえず縮める
for(scanf("%ld",&n);i*i++<n;)
for(;n%i?0:++x%3;j==k?s[k++]=t:0,i=n/i)
for(t=n/i*pow(10,t=log10(i)+1)+i,j=0;j<k&&s[j++]-t;);
s[]への代入の部分もループの中にまとめたほうが短くなる
for(t=n/i*pow(10,t=log10(i)+1)+i,j=0;j<k?s[j++]-t:!(s[k++]=t););
for(t=n/i*pow(10,t=log10(i)+1)+i,j=k;j?s[--j]-t:!(s[k++]=t););
ということでできたのがこれ
long n,s[9999],i,x,k,t;
main(j){
for(scanf("%ld",&n);i*i++<n;)
for(;n%i?0:x++%3;i=n/i)
for(t=n/i*pow(10,t=log10(i)+1)+i,j=k;j?s[--j]-t:!(s[k++]=t););
printf("%d",k);
}
161B