C、109 97バイトおよび正当性の証明
私は自分のソリューションを作成していましたが、@ steveverrillは私にそれを打ち負かしました。使用した戦略の正当性の証拠を含めたので、私はそれをすべて同じように共有すると思った。
削減されたコード:
m,n,x;main(){for(scanf("%i%i",&m,&n); n;)putchar(x<m?"# "[x%2*(++x^m||~n&1)&&n^1]:(x=0,n--,10));}
削減前:
m,n,x;
main(){
for(scanf("%i%i",&m,&n); n;)
/* If x == m, prints out a newline, and iterates outer
* loop (x=0,n--) using comma operator.
* Otherwise, paints a '#' on :
* Every even column (when x%2 is 0)
* On odd columns of the last row (++x^m||~n&1 is 0)
* On the first row (when n^1 is 0)
* And a ' ' on anything else (when predicate is 1) */
putchar(x<m?"# "[x%2*(++x^m||~n&1)&&n^1]:(x=0,n--,10));
}
戦略と証明:
最大ペリミッター方程式(M + 1)(N + 1)-((M + 1)(N + 1))mod 2の正しさを仮定すると、以下は使用される最適戦略を説明し、帰納法によってその正しさを証明します。
奇数のMの場合、M / 2 + 1本の指で手のような形を描きます。例:
3x2
# #
###
5x3
# # #
# # #
#####
ここで、この戦略が帰納法によってすべての奇数Mに最適であることを証明します。
基本ケース: M = N = 1
単一のセルが塗りつぶされます。(1 + 1)*(1 + 1)= 2 * 2 = 4であり、正方形には4つの辺があるため、解は正しいです。
幅の帰納:
手形戦略が(N、M-2)に対して機能すると仮定します。ここで、Mは奇数です。つまり、そのペリミッターは最適で、(N + 1)(M-2 + 1)+((M -1)(N + 1))mod 2。ここで(N、M)で機能することを示します。
指を追加するプロセスにより、ポリゴンから1つのエッジが削除され、3 + 2Nが追加されます。例えば:
5x3 -> 7x3
# # # $
# # # $
#####$$
これを、以前の境界が最適であるという仮説と組み合わせると、新しい境界は次のようになります。
(N + 1)*(M - 2 + 1) - ((M+1)*(N+1)) mod 2 - 1 + 3 + 2*N
(N + 1)*(M + 1) - ((M-1)*(N+1)) mod 2 - 2(N + 1) - 1 + 3 + 2*N
(N + 1)*(M + 1) - ((M-1)*(N+1)) mod 2
モジュロ2算術を扱っているため、
((M-1)*(N+1)) mod 2 = ((M+1)*(N+1)) mod 2
したがって、指を追加して幅を広げると、最適な周囲長になることがわかります。
高さの誘導:
手形戦略が(N-1、M)で機能すると仮定します。ここで、Mは奇数です。つまり、その周囲は最適で、N(M + 1)+((M + 1)N)modです。 2。ここで(N、M)で機能することを示します。
手の高さを増やすと、最初と1つおきのxインデックスにある指が伸びるだけです。各高さの増加のために、各フィンガーは、周辺への2つを追加し、存在する(M + 1)/ 2本の指、したがって、増加のNの増加につながる2(M + 1)/ 2 = M + 1で境界線。
これを仮説と組み合わせると、新しい境界線は次のようになります。
N*(M + 1) + ((M+1)*N) mod 2 + M + 1
(N + 1)*(M + 1) + ((M+1)*N) mod 2
モジュラー演算を使用すると、次のように最終項を簡略化できます。
(N + 1)*(M + 1) + ((M+1)*(N+1)) mod 2
すべてのN> 0および奇数M> 0に対して解が最適であることを証明します。
偶数のMの場合、奇数のMの場合と同じようにボードに入力しますが、最後のセグメントにクレネレーションを追加します。例えば:
4x3
# ##
# #
####
6x4
# # #
# # ##
# # #
######
この戦略が最適であることを証明しました。
偶数Mの帰納法:
解が(N、M-1)に対して正しいと仮定し、奇数M-1(最後のケースで証明されたように)で、(N + 1)M-( M(N + 1))mod 2。ここで、(N、M)で機能することを示します。
指を増やすように、各クレネレーションはポリゴンの周囲に2を追加します。複製の総数は(N + N mod 2)/ 2で、合計でN + N mod 2の境界が追加されます。
これを仮説と組み合わせると、新しい境界線は次のようになります。
(N + 1)*M - (M*(N+1)) mod 2 + N + N mod 2
(N + 1)*(M + 1) - (M*(N+1)) mod 2 + N mod 2 - 1
(N + 1)*(M + 1) - (M*(N+1)) mod 2 - (N + 1) mod 2
私たちはそれを持っています
(M*(N+1)) mod 2 - (N + 1) mod 2 = ((M+1)*(N+1)) mod 2
Nが奇数の場合、これは0 = 0に減少し、Nが偶数の場合、
- A mod 2 - 1 = -(A + 1) mod 2
したがって、戦略はすべてのM、N> 0に最適です。