原博:http://blog.csdn.net/obsolescence/article/details/51999832
因为只有数字0和1,所以只有两种情况,以1开头和以0开头。分别记录数组中出现的1和0的个数。然后判断0和1开头哪个符合要求。若都符合取答案小的那个。
然后,根据输入的m个数,来把n中每一段取出来,经行处理,如果发现这一段中有不符合的,就在往后最近的位置找一个符合的,下标相减,就是移动的次数。为了方便,最好在存N个数的时候下标从1开始。
#include<stdio.h>
#include<algorithm>
using namespace std;
int a1[20],a2[20],b[20],n,m;
int funo(int j,int s1)
{
int i,ans=1000000;
s1^=1;
for(i=j+1;i<=n;i++)
{
if(a1[i]==s1)
{
ans=i-j;
int t=a1[i];
a1[i]=a1[j];
a1[j]=t;
break;
}
}
return ans;
}
int funz(int j,int s2)
{
int i,ans=1000000;
s2^=1;
for(i=j+1;i<=n;i++)
{
if(a2[i]==s2)
{
ans=i-j;
int t=a1[i];
a2[i]=a2[j];
a2[j]=t;
break;
}
}
return ans;
}
int main()
{
while(scanf("%d%d",&n,&m)!=EOF)
{
int i,j,z,o,y,ans1,ans2,f,t;
z=0;
o=0;
ans1=1000000;
ans2=1000000;
for(i=1;i<=n;i++)
{
scanf("%d",&a1[i]);
if(a1[i]==1)
o++;
else
z++;
a2[i]=a1[i];
}
y=0;
for(i=1;i<=m;i++)
{
scanf("%d",&b[i]);
if(i%2!=0)
y+=b[i];
}
if(y==o)
{
f=0,t=0;
ans1=0;
for(i=1,j=1;i<=m;i++)
{
for(j=t+1;j<=t+b[i];j++)
{
if(a1[j]==f)
{
ans1+=funo(j,a1[j]);
}
}
f^=1;
t+=b[i];
}
}
if(y==z)
{
f=1,t=0;
ans2=0;
for(i=1,j=1;i<=m;i++)
{
for(j=t+1;j<=t+b[i];j++)
{
if(a2[j]==f)
{
ans2+=funz(j,a2[j]);
}
}
f^=1;
t+=b[i];
}
}
printf("%d\n",min(ans1,ans2));
}
}