题目大意:
类似开关灯的题。改变一个,与他相邻的两个也会改变,问最少改变几个可以让这个序列变成0
分析:
反转决策。开关会影响3个灯,所以我们每次求连续3个,如果3个第一个是关的,说明这个区间不用反转;否则这 个区间需要反转。因此我们用一个数组f[i]表示[i,i+2]之间是否应该反转。 但是这题目需要注意下,因为第一盏灯比较特殊,只影响2个灯,因此我们需要添加第0项来补满3个,然后通过第 0盏枚举出第一盏灯是否应该反转
code:
#define debug //#define opentext #include<stdio.h> #include<math.h> #include<cmath> #include<queue> #include<stack> #include<string> #include<cstring> #include<string.h> #include<algorithm> #include<iostream> #include<vector> #include<functional> #include<iomanip> #include<map> #include<set> #define pb push_back #define dbg(x) cout<<#x<<" = "<<(x)<<endl; #define lson l,m,rt<<1 #define cmm(x) cout<<"("<<(x)<<")"; #define rson m+1,r,rt<<1|1 using namespace std; typedef long long ll; typedef pair<int,int> pii; typedef pair<ll,ll>PLL; typedef pair<int,ll>Pil; typedef pair<ll,int>Pli; const ll INF = 0x3f3f3f3f; const ll inf=0x7fffffff; const double eps=1e-8; const int maxn =100005; const int N = 510; const ll mod=1e9+7; const ll MOD=10007; //------ //define int a[21]; int f[21]; int ans=INF; //turn int turn(int hv){ memset(f,0,sizeof(f)); a[0]=hv; int sum=0; int cnt=0; for(int i=0;i<20;i++){ if((a[i]+sum)&1){ cnt++; f[i]=1; } sum+=f[i]; if(i-2>=0){ sum-=f[i-2]; } } cout<<cnt<<endl; if((a[20]+sum)&1)return INF; return cnt; } //solve void solve() { for(int i=1;i<21;i++)cin>>a[i]; cout<<min(turn(0),turn(1)); } int main() { ios_base::sync_with_stdio(false); //-----------freopen------------------- #ifdef debug freopen("in.txt", "r", stdin); #ifdef opentext freopen("out.txt","w",stdout); #endif #endif //------------------------------------- cin.tie(0); cout.tie(0); solve(); //-----------opentext------------------ #ifdef opentext fclose(stdin); fclose(stdout); system("out.txt"); #endif //------------------------------------- return 0; }