再帰アルゴリズム: 不可解なスイッチ「ライトを引く」

再帰アルゴリズム: 不可解なスイッチ「ライトを引く」

[[411620]]

タイトル出典:AcWing[1]。

トピック

「Pull the Light」というゲームをしたことがありますか?

ライトは正方形に配置されています。

各ライトには、プレイヤーが状態を変更するために使用できるスイッチがあります。

各ステップで、プレイヤーは特定のライトの状態を変更できます。

プレイヤーがライトの状態を変更すると、連鎖反応が発生し、このライトの上、下、左、右に隣接するライトの状態もそれに応じて変化します。

点灯しているライトを表すには数字を使用し、消灯しているライトを表すには数字を使用します。

次の状態

  1. 10111
  2. 01101
  3. 10111
  4. 10000
  5. 11011

左上隅のライトの状態を変更すると、次のようになります。

  1. 01111
  2. 11101
  3. 10111
  4. 10000
  5. 11011

真ん中のライトを変更すると、ステータスは次のようになります。

  1. 01111
  2. 11001
  3. 11001
  4. 10100
  5. 11011

ゲームの初期状態がいくつか与えられた場合、プレイヤーがステップ内ですべてのライトを明るくすることが可能かどうかを判断するプログラムを作成します。

入力フォーマット

入力の最初の行は正の整数です。これは、データ内に解決すべき初期ゲーム状態の合計があることを意味します。

次のデータ行はグループに分かれており、各データ グループには行があり、各行には文字があります。

各データ セットはゲームの初期状態を表します。

各データ グループは空白行で区切られます。

出力フォーマット

合計で 行のデータが出力され、各行には 未満の整数が含まれます。これは、入力データ内の対応するゲーム状態ですべてのライトを点灯させるために必要な最小ステップ数を表します。

ゲームの特定の初期状態で、ステップ内ですべてのライトを明るくできない場合は出力します。

データ範囲

サンプル入力:

  1. 3
  2. 00111
  3. 01011
  4. 10001
  5. 11010
  6. 11100
  7.  
  8. 11101
  9. 11101
  10. 11110
  11. 11111
  12. 11111
  13.  
  14. 01111
  15. 11111
  16. 11111
  17. 11111
  18. 11111

サンプル出力:

  1. 3
  2. 2
  3. -1

解決

まず、説明する必要がある 3 つの非常に重要な特性があります。

  • ライトを押す場合、どの順番で押しても問題ありません。どの順番で押しても結果は同じです。
  • ライトを 2 回以上押す必要はありません。2 回押すと押さないのと同じになり、3 回押すと 2 回 + 1 回 (つまり 1 回) 押すのと同じになります。

したがって:

  • ライトを押す順序は重要ではないので、最初に最初の行にあるライトをすべて押すことができます。
  • 最初の列のすべてのライトを押した後、最初の列のすべてのライトを点灯させたい場合、最初の列の点灯していないライトの下にあるライトのみを押すことができることがわかりました(以下は例です)
  1. 最初の行のステータスは 10011 です (1 はライトが点灯していることを示します)
  2. 2行目のアクション01100(1はボタンを押すことを表す)

では、2 列目が完全に点灯していることをどのように確認するのでしょうか? この問題を解決するには、3 列目を使用するしかありません。

では、最後の列 (5 列目) が完全に点灯していることをどうやって確認するのでしょうか? それを確認する方法はありません。

1 列目の押し方が決まると、次の 2 列目、3 列目、4 列目、5 列目の押し方と、すべて点灯できるかどうかが決まることがわかりました。

したがって、任意の入力状態について、最初の行の 32 個のメソッドすべてを走査して、どのメソッドが完全に点灯できるか (5 行目の状態をチェックすることによって)、またこれらの完全に点灯しているメソッドのいずれかの操作数が 6 以下であるかどうかを確認します。はいの場合はオペランドを返し、そうでない場合は -1 を返します。

コード

  1. #include <iostream>
  2. #include <cstring>
  3. #include <アルゴリズム>
  4. 名前空間 std を使用します。
  5.  
  6. const int N = 5 + 5; // セキュリティ強化のため 5 を加算
  7. // 入力ストリームの各行にはスペースがないので、受信時に文字列を使用する方が便利であることに注意してください。
  8. char g[N][N]; // ライトの現在の状態を記録する
  9.  
  10. // 右上、左下、中央
  11. 整数dx[5] = {0, 1, 0, -1, 0};
  12. dy [5] = {1, 0, -1, 0, 0};
  13.  
  14. // x 行目と y 列目に従って、上下左右の 5 つのライトを反転します。
  15. void 回転( int x, int y)
  16. {
  17. ( int i = 0; i < 5; ++ i)の場合
  18. {
  19. int a = x + dx[i]、b = y + dy[i];
  20. (0 <= a && a < 5 && 0 <= b && b < 5)の場合
  21. g[a][b] = g[a][b] == '1' ? '0' : '1' ;
  22. }
  23. }
  24.  
  25. 整数 仕事()
  26. {
  27. 整数ans = 2e9;
  28. // 最初のループ、最初の行の押下をすべて走査します
  29. // kは圧縮状態であり、最小値0b00000は押されていないことを意味します。
  30. // 最大値0b11111はすべての押下を表します
  31.      
  32. // バックアップ。次の操作によりgが変更されるため
  33. charバックアップ[N][N];
  34. memcpy(バックアップ、g、gのサイズ);
  35.  
  36. ( int k = 0; k < (1 << 5); ++ k)の場合
  37. {
  38. // gが入力gであることを確認する
  39. memcpy(g, バックアップ, バックアップのサイズ);
  40.  
  41. // 最初の行が k の場合、操作の合計数は..
  42. int res = 0; // resを使用して記録する
  43.  
  44. // k を実行します (k に応じて最初の行を押します)
  45. ( int j = 0; j < 5; ++ j)の場合
  46. {
  47. (k >> j & 1) の場合
  48. {
  49. 解像度++;
  50. ターン(0, j);
  51. }
  52. }
  53.          
  54. // 最初の行は確定し、2行目は確定する
  55. // 2行目だけが妥当なので
  56. // 最初の行を点灯する
  57. // 同様に、2行目が決定された後、3行目は2行目によって決定されます
  58. ( int i = 0; i < 4; ++ i)の場合
  59. {
  60. ( int j = 0; j < 5; ++ j)の場合
  61. {
  62. g[i][j] == '0'場合
  63. {
  64. 解像度++;
  65. ターン(i + 1, j);
  66. }
  67. }
  68. }
  69.  
  70. // 上記の操作により、最初の4行がすべて明るくなります
  71. // ただし、5 列目は必ずしも完全に点灯する必要はありません。5 列目が完全に点灯している場合にのみ、操作が真に効果的になります。
  72. ブール成功 = true ;
  73. ( int j = 0; j < 5; ++ j)の場合
  74. {
  75. g[4][j] == '0'場合
  76. {
  77. 成功 = false ;
  78. 壊す;
  79. }
  80. }
  81.          
  82. // 有効な操作であれば、スイッチが何回押されたかを確認します
  83. if (成功) ans = min (res, ans);
  84. }
  85.      
  86. // 質問に応じて出力値を返します
  87. 答えが 6 より大きい場合は-1 を返します
  88. 回答を返す;
  89. }
  90.  
  91. intメイン()
  92. {
  93. 整数n;
  94. cin >> n;
  95. (n -- ) の 
  96. {
  97. ( int i = 0; i < 5; ++ i) cin >> g[i] ;
  98. printf( "%d\n" , work ());
  99. }
  100. }

参考文献

[1]

アクウィング: https://www.acwing.com/

<<:  エンティティと値オブジェクトの特性を識別する

>>:  データセットと DataLoader を使用して PyTorch でデータをカスタマイズする

ブログ    

推薦する

マスク氏「高度なAIの開発は非常にリスクが高い。OpenAIはアルトマン氏を解雇した理由を明らかにすべき」

11月20日、テスラのCEOイーロン・マスク氏は、高度な人工知能(AI)技術の開発には大きな潜在的...

マイクロソフト、Nvidia が 5300 億の NLP モデル「Megatron-Turing」をリリース、価格は A100 で 4480 台

[[428336]]この記事はAI新メディアQuantum Bit(公開アカウントID:QbitAI...

調査:アーティストの半数以上がAIによる描画は作品制作に役立たないと考えている

近年、人工知能(AI)は芸術作品の創造において驚くべき能力を発揮しています。テキストボックスに文章を...

AI言語モデルのオープンソース化による10のプラスとマイナスの影響

GPT や PaLM などの独自のソフトウェアが市場を支配していますが、多くの開発者は依然としてオー...

コミュニティオーナーの中には顔認識に抵抗する人もいる。「私が家にいないときは、すべて知っている」

Chinanews.com 北京、12月29日(記者 呉涛)最近、一部のユーザーからChinane...

2020 年の AI チャットボット技術予測

2020 年に入り、さまざまな業界で人工知能技術の導入が進み続けています。この二次微分効果は、ビジネ...

ビジネスにおいて人工知能との共生関係を築くには?

現代では、意図的か否かに関わらず、私たちは皆、人工知能に触れたり、人工知能を使用したりしています。私...

...

研究者らは、キーボードの打鍵音からデータを盗むためのディープラーニングモデルを最大95%の精度で訓練することに成功した。

8月7日のニュース、キーボードで入力した内容が他人に聞かれる可能性があることをご存知ですか?英国の...

コロナウイルスのパンデミックはデジタル音声技術に新たな刺激を与えた

突然、タッチを恐れるようになった世界で、音声テクノロジーはまったく新しい様相を呈し始めています。 [...

2021 年に注目すべき 3 つのデータ分析と AI のトレンド

組織が新型コロナウイルス感染症のパンデミックを乗り越えていく中で、データ分析と AI の ROI を...

自動運転業界は2021年に爆発的な成長を遂げるでしょうか?

2020年は自動運転業界が徐々に安定する年だ。ウェイモなどの巨大企業が商業化の模索を開始し、テスラ...

技術革新は「プロトタイプ」で止まるわけにはいかない…

[[270666]] [51CTO.com クイック翻訳] 昨今、クラウドコンピューティング、ブロ...

調査:ブラジルのAIスタートアップの50%以上がサンパウロ州に拠点を置く

ブラジルの新たな調査によると、人工知能関連の製品やサービスの開発に注力している企業の半数以上がサンパ...

正確な画像認識を望むなら、AIデータの精度を効果的に向上させることが鍵となる

技術の継続的な反復的発展により、人工知能の応用は人々の日常生活に巧妙に浸透してきました。インテリジェ...