题目传送门
题意:
给你一个01串,要你对其中字符进行修改,使得修改后的01串每两个相邻的1的距离为k,只有1个1或者全是0的串也算合法串,问最小操作步数。
数据范围:
n<=1e6,k<=n
思路:
先假设全部关闭,就是cnt个,然后通过枚举余数作为第一个,以k为周期遍历,sum代表当前可减少代价,遇到1就sum++,0就sum–,通过ma维护sum的最大值,最后cnt-ma就是答案。
#include<bits/stdc++.h>
#define endl '\n'
#define null NULL
#define ls p<<1
#define rs p<<1|1
#define fi first
#define se second
#define mp make_pair
#define pb push_back
#define ll long long
#define int long long
#define vi vector<int>
#define mii map<int,int>
#define pii pair<int,int>
#define ull unsigned long long
#define all(x) x.begin(),x.end()
#define IOS ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
#define ct cerr<<"Time elapsed:"<<1.0*clock()/CLOCKS_PER_SEC<<"s.\n";
char *fs,*ft,buf[1<<20];
#define gc() (fs==ft&&(ft=(fs=buf)+fread(buf,1,1<<20,stdin),fs==ft))?0:*fs++;
inline int read(){int x=0,f=1;char ch=gc();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=gc();}
while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=gc();}
return x*f;}
using namespace std;
const int N=1e6+5;
const int inf=0x7fffffff;
const int mod=998244353;
const double eps=1e-6;
signed main()
{
int t;
cin>>t;
while(t--)
{
int n,k;
cin>>n>>k;
string s;
cin>>s;
int cnt=0;
for(auto i:s) cnt+=i-'0';
int ans=2e18;
int ma=0;
for(int i=0;i<k;i++)
{
int sum=0;
for(int j=i;j<n;j+=k)
{
if(s[j]=='1')
sum++;
else
sum--;
sum=max(0LL,sum);
ma=max(ma,sum);
}
}
cout<<cnt-ma<<endl;
}
}