【夏老師講模擬卷系列149】詳解四省聯(lián)考(數(shù)學(xué)·全部題目)

#include <iostream>
using namespace std;
//按動開關(guān),注意二維數(shù)組在內(nèi)存中的分布方式
void turn(bool *arr, int n, int x, int y) {
arr[y + x * n] ^= 1;
//對左側(cè)開關(guān)改變狀態(tài)
if (y - 1 >= 0) {
arr[y - 1 + x * n] ^= 1;
}
//對右側(cè)開關(guān)改變狀態(tài)
if (y + 1 <= 2) {
arr[y + 1 + x * n] ^= 1;
}
//對上側(cè)開關(guān)改變狀態(tài)
if (x - 1 >= 0) {
arr[y + x * n - n] ^= 1;
}
//對下側(cè)開關(guān)改變狀態(tài)
if (x + 1 <= 2) {
arr[y + x * n + n] ^= 1;
}
}
int main() {
bool end[9] = {1, 0, 0, 0, 0, 0, 0, 0, 0}; //結(jié)束狀態(tài)
int ans[8];//存儲結(jié)果,如果最終結(jié)果不符合要求,就存-1
for (int i = 0; i < 8; i++) {
int cnt = 0; //翻轉(zhuǎn)次數(shù)
bool start[9] = {0, 0, 0, 0, 0, 0, 0, 0, 0}; //起始狀態(tài)
//先對第一行狀態(tài)進行枚舉(內(nèi)存中是第0行)
if (i & 1 == 1) {
turn(start, 3, 0, 0);
cnt ++;
}
if ((i >> 1) & 1 == 1) {
turn(start, 3, 0, 1);
cnt ++;
}
if ((i >> 2) & 1 == 1) {
turn(start, 3, 0, 2);
cnt ++;
}
/*
開始從第二行第一列開始,逐行遍歷。
若上一行結(jié)果與答案不符,就按動開關(guān),使上一行結(jié)果符合要求,
最終檢測最后一行結(jié)果是否與結(jié)果相同。
一個開關(guān)不能按兩次,否則次數(shù)不是最小,
因為逐行遍歷,只有按下一行才能改變上一行的結(jié)果
*/
for (int j = 1; j < 3; j++) {
for (int k = 0; k < 3; k++) {
if (start[j * 3 - 3 + k] != end[j * 3 - 3 + k]) {
turn(start, 3, j, k);
cnt++;
}
}
}
for (int k = 0; k < 3; k++) {
//最后一行不符合結(jié)果,結(jié)果數(shù)組內(nèi)存上-1
if (start[6 + k] != end[6 + k]) {
ans[i] = -1;
goto l1;
}
}
ans[i] = cnt;
l1:
continue;
}
//選出最小結(jié)果
int min = 9;
for (int i = 0; i < 8; i++) {
if (ans[i] < min && ans[i] > 0) {
min = ans[i];
}
}
cout << min << endl;
}