UVALive 6832Bit String Reordering

来源:互联网 发布:消除噪音软件 编辑:程序博客网 时间:2024/05/18 03:10

题意:

    给定两种类型字符串,第一个是直接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;}}



0 0