题意
有20个碗依次排列,有的碗口朝上,有的碗口朝下,希望所有的碗口都能朝上,每次翻动某个碗时,左边和右边的碗也会翻转到相反的状态,问要想将这些碗碗口都朝上,至少要翻动多少次
思路
典型的开关(翻转)问题,开关问题例题,此时每次只需要翻转三个,则进行贪心的选取,一旦碰到1就将其与之后的三个元素全部翻转。当然第20号碗不能单独进行翻转。需要注意的一点是,第一个碗是否反转不能使用贪心,碗口朝上就不翻转会带来错误解:
001000000 001000000 001000000,如果我们在第一个碗进行翻转,那么 111000000 111000000 111000000,再在第二个碗进行翻转即得到答案。但是如果第一个碗不翻转,那将会需要更多次。因此第一个碗我们进行特判,分翻与不翻分别讨论,取最小的步数作为最终结果。
#include<iostream>
#include<iomanip>
#include<vector>
#include<algorithm>
#include<map>
#include<queue>
#include<string.h>
#include<math.h>
using namespace std;
#define ll long long
#define inf 1e9
#define MAX 100000
ll b[20], res = 0, tmp = inf, a[20];
int main(){
for (ll i = 0; i < 20; i++)cin >> b[i];
for (ll k = 0; k < 2; k++) {
for (ll i = 0; i < 20; i++) a[i] = b[i];
res = 0;
if (k == 1) { a[0] ^= 1; a[1] ^= 1; res = 1; }
for (ll i = 0; i < 19; i++) {//最后一个不能单独拱
if (a[i] == 1) {
res++; a[i] ^= 1;
if (i + 1 < 20) a[i + 1] ^= 1;
if (i + 2 < 20) a[i + 2] ^= 1;
}
}
if (res < tmp&&a[19] == 0) tmp = res;
}
cout << tmp << endl;
}