欢迎光临散文网 会员登陆 & 注册

【夏老师讲模拟卷系列149】详解四省联考(数学·全部题目)

2023-02-24 00:57 作者:bili_39970481094  | 我要投稿

#include <iostream>

using namespace std;


//按动开关,注意二维数组在内存中的分布方式

void turn(bool *arr, int n, int x, int y) {

arr[y + x * n] ^= 1;

//对左侧开关改变状态

if (y - 1 >= 0) {

arr[y - 1 + x * n] ^= 1;

}

//对右侧开关改变状态

if (y + 1 <= 2) {

arr[y + 1 + x * n] ^= 1;

}

//对上侧开关改变状态

if (x - 1 >= 0) {

arr[y + x * n - n] ^= 1;

}

//对下侧开关改变状态

if (x + 1 <= 2) {

arr[y + x * n + n] ^= 1;

}

}


int main() {

bool end[9] = {1, 0, 0, 0, 0, 0, 0, 0, 0}; //结束状态

int ans[8];//存储结果,如果最终结果不符合要求,就存-1

for (int i = 0; i < 8; i++) {

int cnt = 0; //翻转次数

bool start[9] = {0, 0, 0, 0, 0, 0, 0, 0, 0}; //起始状态

//先对第一行状态进行枚举(内存中是第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 ++;

}

/*

开始从第二行第一列开始,逐行遍历。

若上一行结果与答案不符,就按动开关,使上一行结果符合要求,

最终检测最后一行结果是否与结果相同。

一个开关不能按两次,否则次数不是最小,

因为逐行遍历,只有按下一行才能改变上一行的结果

*/

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++) {

//最后一行不符合结果,结果数组内存上-1

if (start[6 + k] != end[6 + k]) {

ans[i] = -1;

goto l1;

}

}

ans[i] = cnt;

l1:

continue;

}

//选出最小结果

int min = 9;

for (int i = 0; i < 8; i++) {

if (ans[i] < min && ans[i] > 0) {

min = ans[i];

}

}

cout << min << endl;

}

【夏老师讲模拟卷系列149】详解四省联考(数学·全部题目)的评论 (共 条)

分享到微博请遵守国家法律