https://www.cnblogs.com/huashanqingzhu/p/7278930.html
http://bailian.openjudge.cn/practice/1222
1222:EXTENDED LIGHTS OUT
この質問私は、6つの要素の最初の行が010101であると仮定すると、最初の行の列挙に場所がより困難と考え、明確に考えるように多くの時間を費やしています
、1111 1111 - 2つだけの状態、2つだけの各ランプ動作のオンとオフランプは、切り替えスイッチを押すとしないことにより、私は以前に、0から63まで、すなわち、0000 0000を列挙考え
この考えは間違っています。初期のランプ状態が決定されるため、あなたはいずれかが、周囲の照明に影響を与える可能性が押すので、この状態は、必ずしも1111 1111ありません。
キーは、最終的に列挙の状態が何であるか、それを明確にしているのですか?列挙は、0は操作がないことを示し、スイッチが1を表し、各ランプ、プレスの動作であります
このスイッチ押圧操作の最初の行、6つの可能な2の合計^。限り、最初の行は、各ランプの動作を決定するように、最初の行の状態でランプが最初の行線2が点灯した後に、決定されるランプの位置、ランプのスイッチング動作
- 説明
-
各行が6個のボタン、5行の合計を有し、ボタンのマトリックスを有します。各ボタンの位置は、ランプを持っています。ボタンが押されると、ボタンの位置や周囲の(上部、下部、左、右)の光が再び変更されます。ランプが最初に点灯している場合には、消滅されますされ、ランプが消灯し、点灯される場合。ランプ4の状態を変化させるマトリックスの横ボタン;マトリックスの隅のボタンは、ランプ3の状態を変更するために他のボタンは、ランプの状態5に変更します。
同図において、X印でマトリックスの左側が押下されたボタンを示し、マトリックスは、ランプの状態を変更する権利を表します。各マトリックスランプは初期状態を設定します。あなたはボタンを押して、というようになるまでの各ランプが消灯します。隣接ボタン、複数のランプが押下されると、キャンセル動作が他の動作をもたらすであろう。次の図は、第2の列のボタンの第3及び第5行が押され、行2の状態では、ランプの列4は変化しません。
あなたは、すべてのライトがオフになっているだけのように、押したボタンを決定するプログラムを書くことです。上記の規則によると、私たちは、1)第2プレスで同じボタンが第一押しは、生成された結果を相殺することを知っています。したがって、唯一の各ボタンを1回押すの最大値; 2)各ボタンが押下された順序は、最終結果に影響を及ぼさない; 3)各ランプ点灯ランプの最初の行の2行目に対応するボタンを押してください、あなたは最初の行のすべての光を消すことができます。繰り返しが続く、ランプは全て1,2,3,4-行を消すことができます。同様に、ボタン1,2,3,4,5列を押すと、ランプ5の前にオフにすることができます。
エントリー
5行、6桁(0又は1)を含む各行。隣接する二つの数字の間に単一のスペースで区切られています。0ランプの初期状態が消滅する表し、1の初期状態は、ランプが点灯していることを示し
輸出
5行、6桁(0又は1)を含む各行。隣接する二つの数字の間に単一のスペースで区切られています。1は、対応するボタンを押す必要を表し、0は、対応するボタンを押す必要がないことを示します。
サンプル入力
0 1 1 0 1 0 1 0 0 1 1 1 0 0 1 0 0 1 1 0 0 1 0 1 0 1 1 1 0 0
サンプル出力
1 0 1 0 0 1 1 1 0 1 0 1 0 0 1 0 1 1 1 0 0 1 0 0 0 1 0 0 0 0
問題解決の分析
出典:北郭威先生
• 第2回押して、単一のボタンを、それが第一のプレスが生成された結果を相殺するので、唯一までの各ボタンを一度押す必要
• 各ボタンが押されたため、最終的な結果には影響ありません
• のを各ランプ点灯ランプの線1と、第2行に対応するボタンを押し、すべてのライトが最初の行をオフにする
•は それを繰り返し、すべてのランプ1、2、3、4行を消すことができ
最初の考え:
オフすべてのかどうかを確認するために、最後の光を計算し、各状態のために、全ての可能なボタン(スイッチ)の状態を列挙する。
各ボタンは、2つの状態(押され又は押されていない)を有し、30個のスイッチの合計は、状態の数は2 30 も、タイムアウトを。
状態の数を減らすためにどのようにそれを列挙?
基本的な考え方: 部分がある場合は、ローカルの状態が決定されると、その後、残りの状態の残りは一つだけ、あるいはnの数種を決定することができ、その後のみをローカル状態ができ列挙する必要があります。
この質問には、「ローカル」の存在が意味するか?
観察を通して、ことがわかった最初の行が1ようになっている 「ローカル」
最初の行で識別された各番組のスイッチング動作は、スイッチング動作の後、光の特定の行につながる場合がオンであるので、光の一部はオフです。
(i番目の列が配置されていると仮定して)ランプ番号へのライン1から外れ、その後、唯一の方法は、2行目のスイッチを押すことで、私は、列番目。(1行目のスイッチが使い果たされているため、スイッチ及び第三の行は最初の行に影響を与えないであろう)
全てのランプ1の最初の行にはオフになって、 第2の実施の形態の妥当ラインスイッチング動作のみです。
第二列のスイッチング動作後、三行目のみの操作と合理的プログラムを切り替え、2行目のランプを消灯します。だから、最後の行のスイッチング動作が唯一のプログラムです。
限り、Aで示される最初の行に敷設操作方式として、プログラムの動作は、残りの行に唯一を決定することです。
:すべてのライトの最後の行がオフであるかどうか、プログラムの最後の行のスイッチング動作を計算し、最後の行の後、スイッチング動作を見て
、そうであれば、状態Aは、溶液でない場合、状態は溶液Aではないが、第一再試行する別の状態からライン1。
列挙動作プログラム、状態数が2 ^最初の行のみである6 = 64
状態の練習のない、より少ない数はありませんか?
最初の行を列挙、状態の数は2 ^である5 = 32
コード出典:北郭威の先生は、わずか数追加や変更コメントを作ります。
/ * http://bailian.openjudge.cn/practice/1222 1222:EXTENDED LIGHTS OUT ハードレベル * / 書式#include <メモリ> 書式#include <iostreamの> の#include < 文字列 > の#include <CStringの> 使用して 名前空間STD; int型 GETBIT(チャー C、INT I) // ビットの値を取得 { // Cチャー間GETビット番号I リターン(C >> I)とを1。; } ボイド SetBit(チャー&C、int型 Iは、int型の V)が// 特定の位置に置くか、または0.1 { // V「ビットが私の中のSET Cチャー番号 IF (V) { C | =(1 << I); } 他 { C&=〜(1 << I); } } ボイドフリップ(チャー&C、int型 I)の// 1ビット反転 { // チャーC「ビットをランクIフリップ。 C ^ =(1 << I)を、 } ボイド OutputResult(int型の T、チャー結果[])// 出力結果 { 裁判所未満 << " PAZZLEの#" <<トン<< てendl; 以下のために(int型 i = 0 ; iは< 5 ; iは++ ) { 用(INT J = 0 ; J < 6 ; J ++ ) { COUT << GetBit(結果[I]、j)は、 もし(J < 5 ) 裁判所未満 << " " ; } coutの << てendl; } } int型のmain() { チャー oriLights [ 5 ]; // 元の入力 チャーライト[ 5 ]; // 途中計算結果 チャー結果[ 5 ]; //は、操作の出力端を切り替え、スイッチが表すプレス、0は動作を表していない チャー switchsと、// 行スイッチ情報 INT T。 CIN >> T; 用(int型、T = 1 ; T <= T、T ++ ) { memset(oriLights、0、はsizeof(oriLights))。// 省略した場合ではありません? 以下のために(int型 i = 0 ; iは< 5 ; iは++ ) { 用(INT J = 0 ; J < 6 ; J ++ ) { int型秒; cinを >> 秒; SetBit(oriLights [i]は、J、S)。 } } 用(INT N- = 0 ; N- < 64 ; N - ++)// 操作スイッチの最初の行トラバース64種類 { memcpyを(ライト、oriLights、はsizeof (oriLights)); switchs = N-; //が前提とスイッチ操作方式は、最初の行0が必要 用(int型 iは= 0 ; iが< 5 ; ++ i)は { 結果[I] =のswitchs; // i行目のスイッチ操作スキーム保存 用(INT J = 0 ; J < 6。、J ++)// i行目のランプに従って変形例を { IF(GETBIT(switchs、J ))// 1に等しいj番目のビットがswitchsはi番目の行、j番目のボタンを押す必要を示し、0に等しい、ボタンを押す必要はありませ示し { IF(J> 0 ) フリップ(点灯[I]、J - 1); // 左光変更 フリップ(点灯[I]、J)を; // スイッチポジションランプを変更 IF(J < 5。 ) フリップ(点灯[I]、J + 1); // 右のランプを変更します } } もし(iは< 4 ) ライト[I + 1 ] = ^ switchs; // ランプが次の行に変更 [I] = switchsライト; // I + 1行目のスイッチ操作方式は、i行目のランプの状態によって決定される } IF [(点灯4 ] = = 0 ) { OutputResult(T、結果)。 破ります; } } } リターン 0 ; }