有一个3 * 3 的数字锁,每个数字锁上显示一个数字,数字范围是0~9;
这个锁的特点是,按下一个数字,这个数字以及它的上下左右的数字都会+1;
如果这个数字是9加了1之后就会变成0;
如果对应方向上没有数字,则不会发生任何事
当锁的全部数字变成0时,这个数字锁就解开了,
现在给你一个数字锁,请你求出解这个数字锁的最小操作数。
比赛思路:
感觉好麻烦,因为按了一个其他也都关联着。
无从下手啊。。。
题解思路:
a数组储存每个位置的值,
b数组储存对每个位置操作了几次
就是枚举,总共9个数字,时间也就是<=(109),直接暴力冲;
首先9层for循环枚举对每个位置操作了几次,然后用check函数检查每次的枚举之后锁的状况。
如果每个位置都是0了就更新最小值。
#include<bits/stdc++.h>
using namespace std;
const int MOD=10;
const int inf=0x3f3f3f3f;
#define loop(x) for(x = 0;x < MOD; ++x)
int a[9] = { 7, 1, 4, 3, 6, 8, 9, 5, 2 };
int b[9];
int check() {
if( (a[0] + b[0] + b[1] + b[3]) % MOD
|| (a[1] + b[0] + b[1] + b[2] + b[4]) % MOD
|| (a[2] + b[1] + b[2] + b[5]) % MOD
|| (a[3] + b[0] + b[3] + b[4] + b[6]) % MOD
|| (a[4] + b[1] + b[3] + b[4] + b[5] + b[7]) % MOD
|| (a[5] + b[2] + b[4] + b[5] + b[8]) % MOD
|| (a[6] + b[3] + b[6] + b[7]) % MOD
|| (a[7] + b[4] + b[6] + b[7] + b[8]) % MOD
|| (a[8] + b[5] + b[7] + b[8]) % MOD) return inf;
int result = 0;
for(int i = 0; i < 9; ++i) cout << b[i] << " \n"[i % 3 == 2];
for(int i = 0; i < 9; ++i) result += b[i];
return result;
}
int main(){
int res=inf;
loop(b[0])loop(b[1])loop(b[2])
loop(b[3])loop(b[4])loop(b[5])
loop(b[6])loop(b[7])loop(b[8]){
res=min(res,check());
}
cout<<res<<"\n";
return 0;
}
两个注意点:
1.用define定义了for循环,看起来会清爽很多
2.输出具体的b数组操作数矩阵时用了这个写法来显示矩阵,可以看得更直观
for(int i = 0; i < 9; ++i) cout << b[i] << " \n"[i % 3 == 2];