POJ3185-The Water Bowls--翻转问题

题意

有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;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值