The Water Bowls POJ3185
投稿日: 更新日:
問題:http://poj.org/problem?id=3185
問題
20個の水入れがある。それぞれの水入れは飲むのに適した状態と適さない状態がある。20個の水入れを全て適した状態にするためにひっくり返していく。しかし、ひっくり返す際1つだけでなく左右に隣接する物もひっくり返してしまう。(合計3つをひっくり返す。端の場合は2つ)
初期値1=適さない状態、0=適切な状態が与えられるので、必要な最小の操作回数をもとめてください。
解法
まず、番目をひっくり返す時、ともひっくり返されるが、扱いにくいので、言い換えて、番目をひっくり返す時、もひっくり返されるとする。
そうすると、と状態が並んでいる時、端のを操作する必要があれば、操作し、を反転させる。次にを見る、のように端から処理していけば良い。
ただし、一番端はの3つを反転させるパターンと、の2つを反転させる2パターンがある。そのため、というダミーを追加し、どちらもシミュレーションし、2つのパターンを処理する。
実装
#include <iostream>
#include <vector>
using namespace std;
int flip(vector<bool> undrink){
int n = undrink.size();
int count = 0;
for(int i = 0;i < n-2; ++i){
if(!undrink[i])continue;
count++;
undrink[i] = !undrink[i];
undrink[i+1] = !undrink[i+1];
undrink[i+2] = !undrink[i+2];
}
if(undrink[n-2]){
undrink[n-2] = !undrink[n-2];
undrink[n-1] = !undrink[n-1];
count++;
}
if(undrink[n-1]){
return 9999;
}
return count;
}
void solve(){
const int n = 20;
vector<bool> undrink(n+1);
for(int i = 1;i <= n; ++i){
int x;
cin >> x;
if(x == 1){
undrink[i] = true;
}
}
int ans = flip(undrink);
undrink[0] = true;
ans = min(ans, flip(undrink));
cout << ans << endl;
}
int main(){
ios::sync_with_stdio(false);
std::cin.tie(0);
solve();
return 0;
}