题目:传送门
思路+代码:
/*
首先,k一定是偶数才能0和1数量相同
(1)统计0~k-1个循环节位置上所包含的0或者1的数量
(2)按照循环节上1的数量从小到大排序
(3)将前k/2个循环节位置上的1变成0(因为前面1少,0多),将k/2后面的循环节位置上的1变成0(因为后面1多)
Note:为什么是在k/2的地方作为分界线,因为要求k个数字中1的个数为k/2,0的个数为k/2;
*/
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <utility>
#include <vector>
#include <string>
using namespace std;
typedef pair <int,int> P;
const int N = 1e6+10;
vector <P> vc;
int n,k;
int cnt[N][2];
int main(void)
{
string ss;
cin>>n>>k>>ss;
if(k%2 == 1){
cout<<-1<<endl;
return 0;
}
//统计循环结位置的0或1的个数
for(int i=0;i<k;i++){
for(int j=i;j<n;j+=k){
if(ss[j] == '0') cnt[i][0]++;
else cnt[i][1]++;
}
}
//记录循环节位置并且按照循环节位置上1的数量从小到大进行排序
for(int i=0;i<k;i++) vc.push_back({ cnt[i][1] ,i});
sort(vc.begin(),vc.end());
int ans = 0;
for(int i=0;i<k;i++){
if(i < k/2){ //前面1少
ans += cnt[ vc[i].second ][1];
}
else{ //后面0少
ans += cnt[ vc[i].second ][0];
}
}
cout<<ans<<endl;
return 0;
}