読者です 読者をやめる 読者になる 読者になる

メモ

yukicoderで遊んでいる競プロゆるふわ勢

yukicoder No.428 小数から逃げる夢

問題はこちら
No.428 小数から逃げる夢 - yukicoder

Cではたとえ整数でも190桁の数をそのまま扱うことはできないので工夫が必要
幸いNが小さいので、多倍長の乗算のためのなにがしかを持ち出さなくても1桁ごとに筆算していけば良い

int main(){
	char ans[999]="",s[]="1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991";
	int n,t,i;
	scanf("%d",&n);
	t=0;//繰り上がり
	for(i=189;i>=0;i--){
		t+=(s[i]-'0')*n;
		ans[i]=t%10+'0';
		t/=10;
	}
	printf("%d.%s",t,ans);
	return 0;
}

当然ネックになるのは与えられた小数Dをどのようにして得るか。
indexは必要なら1ずらすとして、小数第i位f(i)をiで表したい。
主要部分である2桁の繰り返しの部分を見ると
iが奇数のとき(i+9)%20/2
iが偶数のとき(i+10)/20
となっている事がわかる。
この偶奇による場合分けを見ていると、最初の9桁をここにまとめるのは難しそう。
ということで最後の1桁をどうにかまとめると次のようになる。

char s[9];
t,i=190;
main(n){
	for(scanf("%d",&n);i;s[--i]=t%10+48,t/=10)t+=(9/i?i:i%2?(i+9)%20/2:(i-9)/20%9+1)*n;
	t=!printf("%d.%s",t,s);
}

133B

ちなみにindexを1つずらすと2B増える

char s[];
t,i=190;
main(n){
	for(scanf("%d",&n);i--;s[i]=t%10+48,t/=10)t+=(i<9?i+1:i%2?(i-9)/20%9+1:(i-9)%20/2)*n;
	t=!printf("%d.%s",t,s);
}

ただしchar配列の大きさを完全に省略出来るようになるので実質は1B増