回 帖 发 新 帖 刷新版面

主题:第42次编程比赛第一题

[center]二进制编码问题[/center]
给定两个二进制编码(0,1序列),请问从一个编码转换成另一个编码所需的最少次数是多少?

编码转换规则:每一次都可以将编码中任意长度的一段倒置(是连续的一段)。 (1010 倒置后为 0101, 111000倒置后为000111)

请编程找出[b]最少[/b]所需要的转换次数。

输入第一行是第一个二进制编码,第二行是第二个进制编码,输出最少的次数(输入输出采用标准输入输出流)

注: 数据保证两个编码肯定可以相互转换。而且编码最长为20个字符。
注:倒置不是0,1互换,而是英文单词reverse的意思
hint:请注意效率问题。

输入事例:
1001
0110

输出事例:
2

输入事例2:
011000
000110

输出事例2:
1

回复列表 (共22个回复)

沙发

test

板凳

//没有好办法,只好蛮干了,广度优先搜索。等着看大家的程序。

#include <stdio.h>
#include <stdlib.h> 
#include <string.h> 
#define MAX 10000

char text[MAX][20];
char str1[] = "0110111000101001";//"01110011001010";
char str2[] = "1001100110110100";//"01101100110010";
int vcti = 0;
int textlongth = 0;
int textlast = 0;
int ceng = 0;

int  chargestr(char * str)
{
    char  chartemp[20];
    int end = 0;
    strcpy(chartemp,str);
    for(int i = 0; i < (strlen(str)/2 + 1); i++)
    {
        if (str[i] != str[strlen(str)-i-1])
        {
            end++;
            str[i] = chartemp[strlen(str)-i-1];
            str[strlen(str)-i-1] =  chartemp[i];
        }
    }
    return end;
}

int streql(char *str1,char *str2)
{
    while((*str1==*str2)&&(*str1))
    {
        str1++;
        str2++;
    }
    return((*str1==NULL)&&(*str2==NULL));
}

getsubstr(char * str)
{
    char  chartemp[20];
    int   end = 0;
    char  strtemp[20] ;
        
    for (int i = 0; i < strlen(str)-1; i++)
    {
        for (int j = i+1; j < strlen(str); j++)
        {
            int k;
            for (k = 0; k <= j-i; k++)
            {
                chartemp[k] = str[i+k];
            }
            chartemp[k]='\0';
            end = chargestr(chartemp);
            if (end == 0) continue;
            strcpy(strtemp,str);
            for (k = 0; k <= j-i; k++)
            {
                strtemp[i+k] = chartemp[k] ;
            }
            int bint = 1;
            for (int itemp = 0; itemp < textlongth; itemp++)
            {
                if (streql(text[itemp], strtemp))
                {
                    bint = 0;
                    break;
                }
            }
            if (bint == 1)    
            {
              //  printf("%s\n",strtemp);
                strcpy(text[textlongth++],strtemp);
            
                if (streql(strtemp,str2))
                {
                    vcti=1;
                    return;
                }
            }
        }
    }

}

void getsubstrfromarr()
{
   // printf("/////////////////////////////////////////\n");
    int ilast = textlast;
    int inow = textlongth;
    textlast = inow + 1;
    ceng++;
    for (int i = ilast; i < inow; i++)
    {
      //  printf("////////\n");
        if (vcti == 1) return;
      //  printf("now is %s\n",text[i]);
        getsubstr(text[i]);
        
    }
}
main()
{    
    //str_arr.RemoveAll();
    if (streql(str1,str2))
    {
        printf("the end is 0 !!!");
        return;
    }
    char strtemp1[20];
    char strtemp2[20];
    strcpy(strtemp1,str1);
    strcpy(strtemp2,str2);
    int i = 0;
    while (strtemp1[i]==strtemp2[i])
    {
        i++;
    }
    int j =strlen(str1)-1;
    while (strtemp1[j]==strtemp2[j])
    {
        j--;
    }



    for (int k = 0; k < j-i+1; k++)
    {
        str1[k] = strtemp1[i+k];
        str2[k] = strtemp2[i+k];
    }
    str1[k]='\0';
    str2[k]='\0';
    textlongth = 1;
    strcpy(text[0],str1);
    while  (vcti == 0) 
    {
        getsubstrfromarr();
    }

    printf("the end is %d !!!\n",ceng);
}

3 楼

#include <stdio.h>
#include <stdlib.h>
#define M    20

int reverse(int *a, int *b, int n)
{
    int i = 0, j, k, temp;
    int count = 0;
    bool bCmp = true;
    while (i < n)
    {
        int num = n - 1;
        for (j = n-1; j >= i; j --)
        {
            if (a[i] == b[j])
            {
                temp = j;
                num --;
                for (k = i; k <= j; k ++)
                {
                    if (a[k] == b[temp])
                        temp --;
                    else
                        break;
                }
                if (temp == i - 1)
                {
                    count ++;
                    i = j + 1;
                    break;
                }
            }
            if (i == j && a[i] != b[j])
                bCmp = false;
        }
        if (!bCmp)
        {
            count = 0;
            break;
        }
    }
    return count;
}

int main()
{
    int a[M], b[M];
    char input, input_string[2];
    int count1 = 0, count2 = 0;
    while (input != '\n')
    {
        input = getchar();
        input_string[0] = input;
        input_string[1] = '\0';
        a[count1] = atoi(input_string);
        count1 ++;
    }
    input = 'c';
    while (input != '\n')
    {
        input = getchar();
        input_string[0] = input;
        input_string[1] = '\0';
        b[count2] = atoi(input_string);
        count2 ++;
    }
    if (!reverse(a, b, count2 - 1) || count1 != count2)
        printf("两个二进制数不可转换!\n");
    else
        printf("%d\n", reverse(a, b, count1 - 1));
    return 0;
}

4 楼

答案是什么

5 楼

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <istream.h>
/*找出s2和s1最左边倒置后相同的最大匹配的字符串
  比如10110101和01011101就是10
  比如 111000011111 和 111100001111 就是 11100001111
*/
char *StrLike(char *s1,char *s2)
{
    int iRet=0;
    char *s3,*s4;
        
    s4=strdup(s2);
    strrev(s4);
    while(1){
        s3=strstr(s1,s4);
        if((s3!=NULL)&&(strncmp(s1,s3,strlen(s3))==0))
            return s4;
        s4++;
    }
    return NULL;
}
int StrChange(char *s1,char *s2)
{
    int iRet=0,l,i=0;
    char *s3;

    if(strlen(s1)!=strlen(s2)) return -1;
    while((s1[0]!='\0')||(s2[0]!='\0')){
        if(s1[0]==s2[0]){
            s1++;
            s2++;
            continue;
        }
        s3=StrLike(s1,s2);
        if(s3==NULL) return -1;
        l=strlen(s3);
        s1+=l;
        s2+=l;
        iRet++;
    }
    return iRet;
}
int main()
{
    int i=0,n=50;
    char *s1,*s2;

    s1=(char*)malloc(sizeof(char)*n);
    s2=(char*)malloc(sizeof(char)*n);
    cin>>s1;
    cin>>s2;
/*    
    strcpy(s1,"1110000111110");
    strcpy(s2,"1111000011101");
*/    
    i=StrChange(s1,s2);
    if(i<0)
        printf("Enter String1=%s\nEnter String1=%s\nCan't Change.\n",s1,s2);
    else 
        printf("Enter String1=%s\nEnter String1=%s\nChange Number=%d.\n",s1,s2,i);
    system("PAUSE");
    return 0;
}

6 楼

看一下到底是什么东东

7 楼

随便写了个,感觉一些算法没啥依据
///////////////////////////////
#include <iostream >
#include <string>
using namespace std;
int times=0;
int strtoint(string str);
void easynum(int *a,int *b);
void revbegin(int x,int y);
int main()
{int num1,num2;
string str1,str2;
 cin>>str1;
 cin>>str2;
 num1=strtoint(str1);
 num2=strtoint(str2);
 easynum(&num1,&num2);
 revbegin(num1,num2);
 cout<<times<<endl;
return 0;
}
//////////////////////////////////
void easynum(int *a,int *b)
{
while((*a%2)==(*b%2))
{*a/=2;
*b/=2;
}
}
//////////////////////////////////
void revbegin(int x,int y)
{

if(x==y)
return;
times++;
int digit1[20],digit2[20];
int tmp1=x;
int tmp2=y;
int dignum=0;
int flag=0;
int tmp,flag1=2;
while(tmp1||tmp2)
{digit1[dignum]=tmp1%2;
digit2[dignum++]=tmp2%2;
tmp1/=2;
tmp2/=2;
}

int len=0;
for(int i=2;i<=dignum;i++)
{tmp=0;tmp1=x;tmp2=y;
    tmp2=tmp2>>i;

   for(int j=1;j<=i;j++)
   {tmp2*=2;tmp2+=digit2[j-1];}

   while(tmp2%2==tmp1%2&&tmp1&&tmp2)
   {tmp++;
   tmp1/=2;
   tmp2/=2;
   }

  flag=flag>tmp?flag:(flag1=i,tmp);
}
revbegin(x>>flag1,y>>flag1);
}
//////////////////////////////////////////
int strtoint(string str)
{
int len=str.length ();
int num=0;
for(int i=0;i<len;i++)
{num*=2;
if(str[i]=='0')
num+=0;
else if(str[i]=='1')
num+=1;


}

return num;

}

8 楼

#include <iostream>
#include <bitset>
#include <queue>
using namespace std;

const unsigned char BitReverseTable256[] = 
{
  0x00, 0x80, 0x40, 0xC0, 0x20, 0xA0, 0x60, 0xE0, 0x10, 0x90, 0x50, 0xD0, 0x30, 0xB0, 0x70, 0xF0, 
  0x08, 0x88, 0x48, 0xC8, 0x28, 0xA8, 0x68, 0xE8, 0x18, 0x98, 0x58, 0xD8, 0x38, 0xB8, 0x78, 0xF8, 
  0x04, 0x84, 0x44, 0xC4, 0x24, 0xA4, 0x64, 0xE4, 0x14, 0x94, 0x54, 0xD4, 0x34, 0xB4, 0x74, 0xF4, 
  0x0C, 0x8C, 0x4C, 0xCC, 0x2C, 0xAC, 0x6C, 0xEC, 0x1C, 0x9C, 0x5C, 0xDC, 0x3C, 0xBC, 0x7C, 0xFC, 
  0x02, 0x82, 0x42, 0xC2, 0x22, 0xA2, 0x62, 0xE2, 0x12, 0x92, 0x52, 0xD2, 0x32, 0xB2, 0x72, 0xF2, 
  0x0A, 0x8A, 0x4A, 0xCA, 0x2A, 0xAA, 0x6A, 0xEA, 0x1A, 0x9A, 0x5A, 0xDA, 0x3A, 0xBA, 0x7A, 0xFA,
  0x06, 0x86, 0x46, 0xC6, 0x26, 0xA6, 0x66, 0xE6, 0x16, 0x96, 0x56, 0xD6, 0x36, 0xB6, 0x76, 0xF6, 
  0x0E, 0x8E, 0x4E, 0xCE, 0x2E, 0xAE, 0x6E, 0xEE, 0x1E, 0x9E, 0x5E, 0xDE, 0x3E, 0xBE, 0x7E, 0xFE,
  0x01, 0x81, 0x41, 0xC1, 0x21, 0xA1, 0x61, 0xE1, 0x11, 0x91, 0x51, 0xD1, 0x31, 0xB1, 0x71, 0xF1,
  0x09, 0x89, 0x49, 0xC9, 0x29, 0xA9, 0x69, 0xE9, 0x19, 0x99, 0x59, 0xD9, 0x39, 0xB9, 0x79, 0xF9, 
  0x05, 0x85, 0x45, 0xC5, 0x25, 0xA5, 0x65, 0xE5, 0x15, 0x95, 0x55, 0xD5, 0x35, 0xB5, 0x75, 0xF5,
  0x0D, 0x8D, 0x4D, 0xCD, 0x2D, 0xAD, 0x6D, 0xED, 0x1D, 0x9D, 0x5D, 0xDD, 0x3D, 0xBD, 0x7D, 0xFD,
  0x03, 0x83, 0x43, 0xC3, 0x23, 0xA3, 0x63, 0xE3, 0x13, 0x93, 0x53, 0xD3, 0x33, 0xB3, 0x73, 0xF3, 
  0x0B, 0x8B, 0x4B, 0xCB, 0x2B, 0xAB, 0x6B, 0xEB, 0x1B, 0x9B, 0x5B, 0xDB, 0x3B, 0xBB, 0x7B, 0xFB,
  0x07, 0x87, 0x47, 0xC7, 0x27, 0xA7, 0x67, 0xE7, 0x17, 0x97, 0x57, 0xD7, 0x37, 0xB7, 0x77, 0xF7, 
  0x0F, 0x8F, 0x4F, 0xCF, 0x2F, 0xAF, 0x6F, 0xEF, 0x1F, 0x9F, 0x5F, 0xDF, 0x3F, 0xBF, 0x7F, 0xFF
};

int m[1<<20];
queue<unsigned long> q;
unsigned long s,e;
int n;

//Use table lookuping to reverse continous bits
unsigned long do_transform(unsigned long t,int i,int j)
{
    unsigned long head=t&(~(0xffffffff<<i));
    unsigned long tail=t>>j;
    unsigned long mid=(t>>i)&(~(0xffffffff<<(j-i)));

    mid = (BitReverseTable256[mid&0xff]<<16) |
        (BitReverseTable256[(mid>>8)&0xff]<<8) |
        (BitReverseTable256[(mid>>16)&0xff]);
    mid=mid>>(24-(j-i));
    //mid=(~mid)&(~(0xffffffff<<(j-i)));

    return (head)|(mid<<i)|(tail<<j);
}

//BFS search
int do_search()
{
    if(s==e) return 0;
    m[s]=0;
    q.push(s);
    while(!q.empty())
    {
        unsigned long t=q.front();
        q.pop();
        int time=m[t];
        for(int i=0;i<n;i++)
        {
            for(int j=i+1;j<n+1;j++)
            {
                unsigned long r=do_transform(t,i,j);
                if(m[r]>=0) continue;
                if(r==e) return time+1;
                m[r]=time+1;
                q.push(r);
            }
        }
    }
    return -1;
}
int main()
{
    string str;
    for(int i=0;i<(1<<20);i++) m[i]=-1;

    cin>>str;
    s=bitset<20>(str).to_ulong();
    cin>>str;
    e=bitset<20>(str).to_ulong();;
    n=str.size();

    cout<<do_search();
    return 0;
}

9 楼

顶`~`努力中

10 楼


是什么?

我来回复

您尚未登录,请登录后再回复。点此登录或注册