这道题感觉是道很好的贪心题。主要问题是“怎么贪”。
先附上大佬博客Orz:
http://www.cnblogs.com/ShuraK/p/9557440.html
https://www.luogu.org/blog/342zhuyongqi/solution
主要是让每一组的贡献为2,再想好怎么处理000和111就好了。附上AC代码:
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<iostream>
#include<algorithm>
using namespace std;
const int MAX=100010;
char a[MAX*3];
int ans[MAX],tot;
int main()
{
while(scanf("%s",a+1)==1)
{
int l=strlen(a+1);
int n=l/3;
int num=0;
for(int i=1;i<l;i++)
if(a[i]!=a[i+1])
num++;
if(num+1>=2*n)//一开始满足条件
{
printf("0\n");
continue;
}
tot=0;
for(int i=1;i<l;i+=3)//分为n组
{
char k1=a[i];
char k2=a[i+1];
char k3=a[i+2];
if(k1=='0'&&k2=='0'&&k3=='1')
{
ans[tot++]=i+1;//变第2个数
a[i+1]='1';a[i+2]='0';
}
if(k1=='1'&&k2=='1'&&k3=='0')
{
ans[tot++]=i+1;//变第2个数
a[i+1]='0';a[i+2]='1';
}
if(k1=='0'&&k2=='1'&&k3=='1')
{
ans[tot++]=i;//变第1个数
a[i]='1';a[i+1]='0';
}
if(k1=='1'&&k2=='0'&&k3=='0')
{
ans[tot++]=i;//变第1个数
a[i]='0';a[i+1]='1';
}
if(k1=='0'&&k2=='0'&&k3=='0')
{
if(i==1)//第一组
{
ans[tot++]=1;
a[1]=a[2]='1';
}
else
{
if(a[i-1]=='0')
{
ans[tot++]=i;
a[i]=a[i+1]='1';
}
else
{
ans[tot++]=i+1;
a[i+1]=a[i+2]='1';
}
}
}
if(k1=='1'&&k2=='1'&&k3=='1')
{
if(i==1)//第一组
{
ans[tot++]=1;
a[1]=a[2]='0';
}
else
{
if(a[i-1]=='1')
{
ans[tot++]=i;
a[i]=a[i+1]='0';
}
else
{
ans[tot++]=i+1;
a[i+1]=a[i+2]='0';
}
}
}
}
printf("%d\n",tot);
for(int i=0;i<tot-1;i++)
printf("%d ",ans[i]);
printf("%d\n",ans[tot-1]);
}
return 0;
}