【题目大意】:给出n盏灯,给出一个区间范围D。每盏灯可以开关1次,每次按第i盏灯[i-d,i+d]的灯全部变,现在给你灯的初始状态,问多少次可以全部灭去。不能输出“impossible”
【解题思路】:1、开关灯的顺序与最小次数无关。2、枚举前d盏灯的操作方式(一共2^d种)对初始状态进行修改,可改可不改。3、然后对于d之后的灯i,如果它的前i-d盏灯是亮着的话,势必要由它操作最后一次,所以经过这样一轮操作之后,我们可以确保前n-d盏灯一定是灭的。4、但是对于最后的d盏灯,我们无法再对其做出任何修改,所以,势必必须满足全灭的时候才能够满足题意。 YY贪心。。。。。。
下午比赛的时候不知道为什么过不了,各种TLE,各种调整之后还是TLE。赛后过了,这是过了的版本,还要是C++,Orz。稍微动一下就会Tle不知道为什么,其实我觉得没多大关系。
【代码】:
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <vector>
#include <queue>
#include <cmath>
#include <string>
#include <cctype>
#include <map>
#include <iomanip>
using namespace std;
#define eps 1e-8
#define pi acos(-1.0)
#define inf 1<<30
#define linf 1LL<<60
#define pb push_back
#define lc(x) (x << 1)
#define rc(x) (x << 1 | 1)
#define lowbit(x) (x & (-x))
#define ll long long
int a[110],now[110];
int n,ans,tmp,d;
int main(){
int T;
scanf("%d",&T);
while (T--){
scanf("%d%d",&n,&d);
for (int i=0; i<n; i++) scanf("%d",&a[i]);
ans=inf;
for (int i=0; i<=(1<<min(d,n))-1; i++){
for (int j=0; j<n; j++) now[j]=a[j];
tmp=0;
for (int j=0; j<d; j++)
if (i&(1<<j)) {
tmp++;
for (int l=max(0,j-d); l<=j+d && l<n; l++) now[l]^=1;
}
for (int j=d; j<n; j++)
if (now[j-d]){
tmp++;
for (int l=max(0,j-d); l<=j+d && l<n; l++) now[l]^=1;
}
for (int j=n-d; j<n; j++) if (now[j]) {tmp=inf; break;}
ans=min(ans,tmp);
}
if (ans==inf)printf("impossible\n");
else printf("%d\n",ans);
}
return 0;
}