首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 开发语言 > C++ >

让小弟我想了2个钟头的迅雷笔试算法题

2012-07-19 
让我想了2个钟头的迅雷笔试算法题对一个有空格的字符串1111 0000,现在做以下规定:1.1只能往右移动,0只能

让我想了2个钟头的迅雷笔试算法题
对一个有空格的字符串"1111 0000",现在做以下规定:
1. 1只能往右移动,0只能往左移动

2. 空格两边的1和0可以移动进入空格

3. 1可以跳过0进入空格,0可以跳过1进入空格

编程,用最少的步骤,将字符串移动变为"0000 1111",并打印出移动过程。

请各位大侠赐教,真不知道这算法该如何写

[解决办法]
我写的罗里啰嗦。。。。

C/C++ code
#include <stdio.h>void move_char(char *s, char *t);void fun(char *str, int j);int main(){    char str[] = "1111 0000";    int i;    for(i = 0; i < 4; i++)    {        fun(str, i);        move_char(&str[i+5], &str[i]);    }    fun(str, 4);    printf("%s\n", str);    return 0;}void move_char(char *s, char*t){    char temp;    temp = *s;    *s = *t;    *t = temp;    if (*t == '1')    {        printf("[%c] move to [%c]\n", *t, *s);    }    else    {        printf("[%c] form 1111 jump to [%c]\n", *t, *s);    }}void fun(char *str, int j){    while(str[j] != ' ')    {        int i;        for(i = 0; str[i] != ' '; i++)        {            ;        }        move_char(&str[i-1], &str[i]);    }}
[解决办法]
可以采用下面的代码实现。你可以尝试一下:

[code=C/C++][/code]
#include<stdio.h>
#include<string.h>





void MoveChar(char *ch,int i,int pos)
{
char temp;
temp=ch[i];
ch[i]=ch[pos];
ch[pos]=temp;
}
void StrPrint(char *ch)
{
printf("%s\n",ch);
}

int main()
{
char str[] = "11111 00000";
int i=0;
int iLen=strlen(str);
int iNullPos;

StrPrint(str);

for(i = 0; i <iLen; i++)
{
if(' '==str[i])
{ iNullPos=i;
break;
}
else
{
continue;
}
}

MoveChar(str,0,iNullPos);


StrPrint(str);
int j=iLen-1;

for(i=0;i<iNullPos;i++)
{
char temp;
MoveChar(str,i,j);


StrPrint(str);


if(i!=j)
{
MoveChar(str,i+1,j);

StrPrint(str);
}
else
{
break;
}
j--;

}

return 0;
}
 
[解决办法]
探讨

这个问题貌似没有最少步骤
所有方法都一样24步

[解决办法]
2楼就给出了一个不错的解答!!只是没做解释

其实这个题主要是寻找一个循环不变式, 也可以说是把大问题变小问题。

如1111 0000
通过一个循环,可以变为0111 0001, 注意去掉第一个0和最后一个1, 那么该问题就变了转换111 000

那么如何进行这次循环,
其实很简单,1和0都只能通过跳入空格的方式移动,那么第一步做的就是把空格放到第一个位置或者是最后一个位置。
_11110000
然后,0跳入到第一个位置01111_000
再把空格移动到最后一个位置,01111000_
1跳入最后一个位置,0111_0001 
就完成一次循环了。

以后保持这个循环不变,直到完成。

[解决办法]
恩……写了一个好复杂的,得到了两个对称的24步移动法
C/C++ code
 
#include <iostream>

using namespace std;


char question[9] = {'1','1','1','1',' ','0','0','0','0'};

char result[9] =  {'0','0','0','0',' ','1','1','1','1'};


struct statenode

{

char state[9];

statenode *next;

};

statenode *stack = NULL;


int search(int start, int type)

{

if( type == 2 )

{

if( question[start] == '1')



{

if( question[start+1] == ' ' )

return 1;

}

else if( question[start] == ' ' )

{

if( question[start+1] == '0' )

return 1;

}

}

else

{

if( question[start] == '1')

{

if( question[start+1] == '0' && question[start+2] == ' ')

return 1;

}

else if( question[start] == ' ' )

{

if( question[start+1] == '1' && question[start+2] == '0' )

return 1;

}

}

return 0;

}


void move(int start, int type)

{

char tmp;

if( type == 2 )

{

tmp = question[start];

question[start] = question[start+1];

question[start+1] = tmp;

}

else

{

tmp = question[start];

question[start] = question[start+2];

question[start+2] = tmp;

}

}


void savestate()

{

statenode *tmp;

tmp = new statenode;

strcpy( tmp->state, question);

tmp->next = stack;

stack = tmp;

}


void loadstate()

{

statenode *tmp;

strcpy(question, stack->state);

tmp = stack;

stack = stack->next;

delete tmp;

}


int statecmp()

{

statenode *tmp = stack;

while(tmp!=NULL)

{

if( 0 == strcmp( question, (const char *)&(tmp->state) ) )

return 0;

tmp = tmp->next;

}

return 1;

}


void answer()

{

int i,type;

static int step = 0;


for(i=0; i <8; i++)

{

for(type=2; type <4; type++)

{

if( (i+type) <=9 )

{

if( search(i,type) )

{

savestate();

move(i,type);

step++;



if( !strcmp(question, result) )

{

cout < <step < <endl;

statenode *out = stack;

while(out!=NULL)

{

cout < <out->state < <endl;

out = out->next;

}

}



if( statecmp() )

{

answer();

loadstate();

step--;

}

else

{

loadstate();

step--;

}

}

}

}

}

}


void main()

{

answer();

system("PAUSE");

}


[解决办法]
探讨

引用:
可以证明,如果有n个1,n个0的话,这个问题的解就是n^2+2*n步。

应该不是,1和0是等价的
111 00到00 111
反序就是11 000到000 11的过程

[解决办法]
#include <stdio.h>



void printStep( int step, char *buf)
{
printf("step : %d , [%s]\r\n",step,buf);
}
int main(int argc, char **argv)
{
int i = 0;
int l = 0;
int r = 8;
char buf[10] = "1111 0000";
buf[0] = ' ';
buf[4] = '1';
printStep(1,buf);
for( i = 1 ; i < 8 ; )
{
buf[r] = ' ';
buf[l] = '0';

printStep(++i,buf);

buf[++l] = ' ';
buf[r--] = '1';

printStep(++i,buf);
}
return 0;
}




/////////////////////////////////

step : 1 , [ 11110000]
step : 2 , [01111000 ]
step : 3 , [0 1110001]
step : 4 , [0011100 1]
step : 5 , [00 110011]
step : 6 , [000110 11]
step : 7 , [000 10111]
step : 8 , [00001 111]
step : 9 , [0000 1111]

////////////////////////////////
[解决办法]

探讨

0,我错,没看清
证明方法是什么?

热点排行