题意:
给定两种类型字符串,第一个是直接0,1表示的,第二个是用字符数表示,相邻两个间,字符为0或1,求通过交换相邻两个字符,最少用几次,将字符串1变到字符串2。
解题:
首先先确定字符串2的序列,若字符串1中字符1和字符0的数量相同,那么字符串2,可以取两种状态,在两种状态中取少的那种,否则就只有一种,直接计算即可。
如何计算步数?
字符串向后移动,碰到不一致的,便向后找到第一个不一样的字符。该字符位置减去当前字符位置即为代价。同时互换两个位置的值。(直接取非即可)
代码:
#include <iostream>
#include <cstdio>
#include <cstring>
#include <queue>
#include <map>
#include <string>
using namespace std;
int s1[20],s2[20],store[20];
int n,m,cnt_one,cnt_zero,cnt_a,cnt_b,minn,p,tmp;
void assign(bool flag)
{
p=0;
for(int i=1;i<=m;i++)
{
for(int j=1;j<=store[i];j++)
{
if(flag)s2[++p]=1;
else s2[++p]=0;
}
flag=!flag;
}
}
int cal()
{
int res=0;
for(int i=1;i<=n;i++)
{
if(s1[i]!=s2[i])
{
for(int j=i;j<n;j++)
{
if(s2[j]!=s2[j+1])
{
res+=(j+1)-i;
tmp=s2[i];
s2[i]=s2[j+1];
s2[j+1]=tmp;
break;
}
}
}
}
return res;
}
int main()
{
while(cin>>n>>m)
{
bool sign=true;
cnt_one=cnt_zero=cnt_a=cnt_b=0;
for(int i=1;i<=n;i++)
{
cin>>s1[i];
if(s1[i])cnt_one++;
else cnt_zero++;
}
for(int i=1;i<=m;i++)
{
cin>>store[i];
if(sign)cnt_a+=store[i];
else cnt_b+=store[i];
sign=!sign;
}
if(cnt_a==cnt_b)
{
assign(true);
minn=cal();
assign(false);
tmp=cal();
if(minn>tmp)
minn=tmp;
}
else
{
if(cnt_a==cnt_one)
assign(true);
else assign(false);
minn=cal();
}
cout<<minn<<endl;
}
}