回 帖 发 新 帖 刷新版面

主题:第80次编程比赛(08第二学期开学第一炮)

原79次冠军因长时间不再发帖子,故本次由本人开展

[color=0000FF]题目描述:[/color]
现在,有两个正整数A和B,例如A是345,B是478,现在,需要把B插入到A里,
而A有三位,所以有四个位置选择,所得结果分别是:
478345, 347845, 344785, 345478
我们通过对比可以知道,在这当中最小的一个是344785
这两个正整数长度不超过100000位,各个位均不包含数字0
现在的目标是,要找出插入后所能得到的最小的整数,输出这个整数

[color=0000FF]样例输入:[/color]
345 478
12345 678
12 21
12 23

[color=0000FF]样例输出:[/color]
344785
12345678
1212
1223

[color=0000FF]答题要求:[/color]
请完善以下代码(C/C++均可):
[code=c]#include <stdio.h>
#define MAXLEN 100000

//todo: 在此增加你所需要的函数或者变量或者头文件

void deal(char* a, char* b, char* c)
{
    // todo: 在此补充你的处理代码
    // 参数说明: a和b是输入的字符串,c要保存输出结果
}

char a[MAXLEN+1], b[MAXLEN+1], c[MAXLEN*2+1];
int main(void)
{
    while (scanf("%s%s", a, b)!=EOF)
    {
        deal(a, b, c);
        puts(c);
    }
    return 0;
}[/code]

其它信息:
本次比赛以公开答题代码的形式,且附以及时的测试,允许直接在本帖子讨论算法
测试内容:正确性,时间效率,空间效率,代码可读性
本次比赛结束时间3月8日 23:00

[color=FF0000]在本帖子回复广告或比赛无关内容者立即封ID及IP[/color]

回复列表 (共182个回复)

沙发


#include <stdio.h>
#define MAXLEN 100000

//todo: 在此增加你所需要的函数或者变量或者头文件
#include <string.h>
#include <stdlib.h>

void deal(char* a, char* b, char* c)
{
    // todo: 在此补充你的处理代码
    // 参数说明: a和b是输入的字符串,c要保存输出结果
    int i,aLen,bLen;
    char d[MAXLEN*2+1];

    aLen=strlen(a);
    bLen=strlen(b);
    strcpy(c,b);
    strcat(c,a);

    for(i=1;i<=aLen;i++)
    {
        memmove(d,a,i);
        memmove(&d[i],b,bLen);
        memmove(&d[i+bLen],&a[i],aLen-i+1);//包括末尾的'\0'
        if(strcmp(d,c)<0)strcpy(c,d);
        //不用清空d,因为每次都是从d缓冲区的首部开始,且组合串长度都相等
    }
}

char a[MAXLEN+1], b[MAXLEN+1], c[MAXLEN*2+1];
int main(void)
{
    while (scanf("%s%s", a, b)!=EOF)
    {
        deal(a, b, c);
        puts(c);
    }
    return 0;
}

板凳

1楼的代码测试结果:

正确性:完全正确
[color=red]时间效率:极低下[/color]
空间效率:好
可读性:很好

3 楼

[code=c]
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#define MAXLEN 100000

//todo: 在此增加你所需要的函数或者变量或者头文件

inline void move(char* a, char* b, char* c,int i,int aLen,int bLen)
{
     memmove(c,a,i);
     memmove(&c[i],b,bLen);
     memmove(&c[i+bLen],&a[i],aLen-i+1);//包括末尾的'\0'
}


void deal(char* a, char* b, char* c)
{
    // todo: 在此补充你的处理代码
    // 参数说明: a和b是输入的字符串,c要保存输出结果
    int i,aLen,bLen,k;
    aLen=strlen(a);
    bLen=strlen(b);
    i=0;
    while(i<aLen&&a[i]<=b[0])
        i++;
    if(a[i]<b[0]||i==0)
        move(a,b,c,i,aLen,bLen);
    else
    {
        k=1;
        while(k<bLen&&b[k]==b[0])
            k++;
        if(k==bLen||b[k]>b[0])
            move(a,b,c,i,aLen,bLen);
        else
        {
            i--;
            while(a[i]==b[0])
                i--;
            i++;
            move(a,b,c,i,aLen,bLen);
        }
    }
}

char a[MAXLEN+1], b[MAXLEN+1], c[MAXLEN*2+1];
int main(void)
{
    while (scanf("%s%s", a, b)!=EOF)
    {
        deal(a, b, c);
        puts(c);
    }
    return 0;
}[/code]

4 楼

3楼的代码和1楼的同样评价。。。

5 楼


[code=c]
#include <stdio.h>
#define MAXLEN 100000

#include <string.h>

void deal(char* a, char* b, char* c)
{
    char *p;
    int pos=1;
    int i=2;
    int size_a=strlen(a);
    int size_b=strlen(b);
    char *p1,*p2;
    if(*a>*b)
    {
        p1=a;
        p2=b;
        p=c;
        while(*p++=*p2++);
        p--;
        while(*p++=*p1++);
        *p=0;
        return;
    }
    while(i<=size_a)
    {
        p1=b;
        p2=&a[pos];
        int j=pos;
        while(*p1&&*p2)
        {
            if(*p1>*p2) {pos=i;break;}
            else if(*p1==*p2)
            {
                if(p1==b+size_b-1) p1=&a[pos];
                else p1++;
                if(j<i-1) p2=&a[++j];
                else if(j==i-1) p2=b;
                else if(p2!=b+size_b-1) p2++;
                else p2=&a[i];
            }
            else break;
        }
        i++;
    }
    
    p=a;
    char *q=c;
    char *pb=b;
    i=0;
    while(i<pos) *q++=a[i++];
    while(*q++=*pb++);
    q--;
    while(i<size_a) *q++=a[i++];
    *q=0;
}

char a[MAXLEN+1], b[MAXLEN+1], c[MAXLEN*2+1];
int main(void)
{
    while (scanf("%s%s", a, b)!=EOF)
    {
        deal(a, b, c);
        puts(c);
    }
    return 0;
}

[/code]

6 楼

[quote]3楼的代码和1楼的同样评价。。。[/quote]

这个。。效率应该不是一个数量级的吧,可以提供测评方法或数据吗?


7 楼

http://yzfy.org/dis/listpost.php?tid=980
你要在线测评的话可以去这里

三楼的代码没认真看,正确性方面其实是错的

8 楼

#include <stdio.h>
#define MAXLEN 100000

//todo: 在此增加你所需要的函数或者变量或者头文件

inline void move(char* a, char* b, char* c,int i)
{
    char *aa,*bb,*cc;
    aa=a;
    bb=b;
    cc=c;
    int j=i;
    while(i-->0) *cc++=*aa++;
    while(*cc++=*bb++);
    
    cc--;
    while(*cc++=*aa++);
    
    *cc=0;
}
void deal(char* a, char* b, char* c)
{
    // todo: 在此补充你的处理代码
    // 参数说明: a和b是输入的字符串,c要保存输出结果
    int i,aLen,bLen,j,k;
    char *aa;
    aa=a;
    //aLen=strlen(a);
    //bLen=strlen(b);
    i=0;
    while(*aa&&*aa++<=*b)
        i++;
    if(*aa<*b||i==0)
        move(a,b,c,i);
    else
    {
        k=1;
        aa=b;
        while(*aa&&*aa++==*b);
        if(!*aa||*aa>*b)
            move(a,b,c,i);
        else
        {
            i--;
            aa=a;
            while(*aa==*b)
                i--;
            i++;
            move(a,b,c,i);
        }
    }
}

char a[MAXLEN+1], b[MAXLEN+1], c[MAXLEN*2+1];
int main(void)
{
    while (scanf("%s%s", a, b)!=EOF)
    {
        deal(a, b, c);
        puts(c);
    }
    return 0;
}


自己随便测试了下,发现主要慢在数组操作上,但比一楼还是快些,毕竟它复制了那么多次,我只复制一次,太久没有用C/C++,不习惯用指针了,参考了5楼的代码,按原来的算法修改成指针操作了,效率好多了!

9 楼

测试结果:
5楼和8楼的代码逻辑上不正确

10 楼

[quote]测试结果:
5楼和8楼的代码逻辑上不正确[/quote]


发完才看到你的回复,,,第一次错的,第二次也错了

我来回复

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