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

メモ

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

yukicoder No.39 桁の数字を入れ替え

問題はこちら
No.39 桁の数字を入れ替え - yukicoder

上位のほうにある小さい数字と下位の方にある大きい数字を入れ替えればいい

int main(){
	int i,j,k,m,n;
	char s[20];
	gets(s);
	n=strlen(s);
	for(i=0;i<n;i++){
		m=0;
		for(j=i+1;s[j];j++)if(s[j]>=m)m=s[k=j];
		//同じ数字なら下位のものと入れ替えた方が得なのでif文は等号込み
		if(s[i]<m){
			s[i]^=s[k]^=s[i]^=s[k];
			break;
		}
	}
	puts(s);
	return 0;
}

このxorswapは未定義動作であり、場合によってはバグるので、まともなプログラムを書くときは非推奨
バグる
#44081 No.55 正方形を描くだけの簡単なお仕事です。 - yukicoder
#44093 No.55 正方形を描くだけの簡単なお仕事です。 - yukicoder

そんなわけで

char s[11];
i,k;
main(j){
	gets(s);
	for(;k==i&&s[j=i];){
		for(;s[++j]>=s[k]?k=j:s[j];);
		k=s[k]-s[i]?s[i]^=s[k]^=s[i]^=s[k]:++i;
		//入れ替えをしたらkには48以上の値が、しなければ次の初期値iが入る
		//iは10以下なので、「入れ替えてないか」のチェックはk==iでできる
	}
	i=!puts(s);
}

不等号を除算に書き換えて、ループ圧縮。ついでにchar型配列の大きさを誤魔化す

char s[9];
i,j,k;
main(){
	for(gets(s);!s[++j]?k=s[k]-s[i]?s[i]^=s[k]^=s[i]^=s[k]:++i,k==i&&s[j=i]:s[j]/s[k]?k=j:1;);
	i=!puts(s);
}

ここまでたどり着くのに結構悩んだ覚えがあるのだけど、こうやって書いてみるとやってることは基本しかない
125B

全探索も考えてみたけど、こんな感じでループ圧縮していって127B

char s[9];i,j,k,m;main(t){for(gets(s);s[++i];j=0)for(;j<i;j++)for(;++k%3;t=atoi(s),m=m<t?t:m)s[i]^=s[j]^=s[i]^=s[j];i=!printf("%d",m);}
char s[9];i,j,k,m;main(t){for(gets(s);s[++i];j=0)for(;++k%3?s[i]^=s[j]^=s[i]^=s[j],t=atoi(s),m=m<t?t:m:++j<i;);i=!printf("%d",m);}
char s[9];t,j,k,m;main(i){for(gets(s);++k%3?s[i]^=s[j]^=s[i]^=s[j],t=atoi(s),m=m<t?t:m:++j<i?:(j=0,s[++i]););j=!printf("%d",m);}
char s[9];t,j,k,m;main(i){for(gets(s);++k%3?s[i]^=s[j]^=s[i]^=s[j],t=atoi(s),m=m<t?t:m:++j/i?j=0,s[++i]:1;);j=!printf("%d",m);}