メモ

yukicoderでゆるふわgolf

yukicoder No.537 ユーザーID

問題はこちら
No.537 ユーザーID - yukicoder

2つの数A,Bを連結するのは、文字列として処理するのでも良いが、Cだと面倒なので計算をする
数Bの桁数は\lfloor \log_{10} B \rfloor +1で得られるので、AとBをこの順で連結したものはA*10^{\lfloor \log_{10} B \rfloor +1}+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