問題はこちら
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