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