1. 程式人生 > 其它 >CF275A Lights Out 題解

CF275A Lights Out 題解

CF275A Lights Out 題解

Content

有一個 \(3\times 3\) 的矩陣。一開始每個元素都為 \(1\)

你可以對任意的位置進行操作,每次操作將在這個位置上的元素及其上下左右的元素全部由 \(1\) 改為 \(0\) 或者將 \(0\) 改為 \(1\)

現在給定每個位置上的操作次數 \(x_{i,j}\),求執行完全部的操作後矩陣裡每個元素的值。

資料範圍:\(0\leqslant x_{i,j}\leqslant 100\)

Solution

我們可以發現兩個非常顯然的結論:

  • 如果在某個位置上的操作次數為偶數,那麼就相當於沒有做。因為你做了偶數次之後,總會變回原來的元素的值,比如 \(0\rightarrow1\rightarrow0,1\rightarrow0\rightarrow1\)
  • 如果在某個位置上的操作次數為奇數,那麼就相當於只做了一次。由上面我們可以發現,做偶數次之後就相當於沒做,所以做奇數次肯定只有最後一次有效果。

所以我們想到了這樣的一個演算法:先將矩陣上的元素全部初始化為 \(1\),然後找那個位置上的操作次數是奇數次,是奇數次就將這個位置上的元素以及其上下左右的元素全部調換,最後輸出結果。

Code

#include <cstdio>
using namespace std;

int a[7][7], ans[7][7];
const int dx[5] = {0, 0, 0, 1, -1};
const int dy[5] = {0, 1, -1, 0, 0};

int main() {
	for(int i = 1; i <= 3; ++i)
		for(int j = 1; j <= 3; ++j)
			ans[i][j] = 1;
	for(int i = 1; i <= 3; ++i)
		for(int j = 1; j <= 3; ++j) {
			scanf("%d", &a[i][j]);
			if(a[i][j] % 2)	
				for(int k = 0; k < 5; ++k)
					ans[i + dx[k]][j + dy[k]] = 1 - ans[i + dx[k]][j + dy[k]];
		}
	for(int i = 1; i <= 3; puts(""), ++i)
		for(int j = 1; j <= 3; ++j)	printf("%d", ans[i][j]);
}