回 帖 发 新 帖 刷新版面

主题:第68次编程比赛题目

为了让更多的人参与比赛,此次给出两个题目

最大可用内存限制为1G字节

做对第一题为必要条件,只作对第二题的话没有竞选冠军的资格。
如果多人做对第一题,且时间空间均相差无几,则再根据第二题评定结果。

题1、给出数组array[h][w],请为该数组赋值,要求数组中数字的规律为从[0][0]位置开始
按蛇形路径来回递增。如下示例:
array[9][7]
--------------------------------------------------
|    1 |    3 |    4 |   10 |   11 |   21 |   22 |
--------------------------------------------------
|    2 |    5 |    9 |   12 |   20 |   23 |   35 |
--------------------------------------------------
|    6 |    8 |   13 |   19 |   24 |   34 |   36 |
--------------------------------------------------
|    7 |   14 |   18 |   25 |   33 |   37 |   48 |
--------------------------------------------------
|   15 |   17 |   26 |   32 |   38 |   47 |   49 |
--------------------------------------------------
|   16 |   27 |   31 |   39 |   46 |   50 |   57 |
--------------------------------------------------
|   28 |   30 |   40 |   45 |   51 |   56 |   58 |
--------------------------------------------------
|   29 |   41 |   44 |   52 |   55 |   59 |   62 |
--------------------------------------------------
|   42 |   43 |   53 |   54 |   60 |   61 |   63 |
--------------------------------------------------

参赛者需实现的函数如下
int fillArray(int *pArray, int h, int w)

题2、有两个文件file1、file2,文件里存放着若干行的文字, 文件里的内容是乱序的,文字的行数不做上限。假定每行小于80个字符

请找出同时存在与两文件中那些行,并将这些行输出到另一文件fileResult

参赛者需实现的函数如下
int findDuplicateLine(const char *pszFile1, const char *pszFile2, cosnt char *pszFileResult);


判断标准:
(1)正确
(2)时间效率
(3)空间效率
(4)可读性

比赛时间:
    2008年6月29日12:00 -- 2008年7月8日22:00

回复列表 (共20个回复)

11 楼


学习

12 楼


13 楼

//第一题解法:

int fillArray(int *pArray,int h,int w)
{
    int curr_w=0,curr_h=0;
    int last_w=0,last_h=0;
    //更改方向的初始值就可以改变蛇行移动的方向
    //1 2   1 3
    //3 4   2 4
    //-0-   -1-
    int flag = 0,direction = 1;
    int count = 1;
    //判断输入值是否合法
    if( !pArray || !h || !w )
        return -1;
    //进入处理循环
    while( 1 )
    {
        //为当前坐标赋值
        *(pArray+curr_h*w+curr_w) = count;
        //保存坐标,以便更新
        last_w=curr_w,last_h=curr_h;
        //检测是否到达最后一个位置
        if( curr_w >= w-1 && curr_h >= h-1)
            return 0;
        //未到达结束位置当继续处理,根据当前方向移动坐标
        if( direction )
            curr_w--,curr_h++;
        else
            curr_w++,curr_h--;
        //‘碰撞检测’若发生碰撞则应反向
        //  并且需重新计算运动起点
        //  如果与X方向边界发生碰撞
        if( curr_w<0 || curr_w>=w )
        {
            curr_w = last_w,curr_h=last_h+1;
            flag = 1;
        }
        if( curr_h<0 || curr_h>=h )
        {
            curr_h = last_h,curr_w=last_w+1;
            flag = 1;
        }
        //如果转向标记为真,则转向,并清空标记
        if( flag )
            direction = !direction,    flag=0;
        //记数器增加
        count++;
    }
    return 0;
}

/////////////////////////////////////////
//测试代码

#include <stdio.h>
#define W 10
#define H 11

int main(void)
{
    int i,j;
    int buf[H][W];
    fillArray((&buf[0][0]),H,W);
    for( i=0;i<H;i++ )
    {
        for( j=0;j<W;j++ )
            printf("%5d",buf[i][j]);
        putchar('\n');
    }
    return 0;
}

///////////////////////////////////////////
//新来比较菜,第2题做出来了,但是代码太长,
//要BS就BS吧,[em10]
//
//文件处理这块没时间优化了,忙得要死啊。。
//
///////////////////////////////////////////
#include <stdio.h>
//任意设置最多行数,最多字书
//按要求字书一行最多80,行数任意,内存不够的时候,
//程序会自动使用硬盘来解决存储问题
#define MAXLINES 1024
#define MAXWORDS 80
//定义了一个结构用来放读出的数据
//并提供了基础操作
typedef struct _auto_ary
{
    char _str[MAXLINES][MAXWORDS];
    char file_name[10];
    int count;
    FILE * tmp_f;
}
ARRAY,*PARRAY;
int _init(PARRAY a,int num)
{
    sprintf(a->file_name,"tmp%d",num);
    a->tmp_f = fopen(a->file_name,"w+");
    if( !a->tmp_f )
        return -1;
    a->count = 0;
    return 0;
}
int _add(PARRAY a,const char* str)
{
    if( a->count < MAXLINES )
        strcpy(&(a->_str[a->count][0]),str);
    else
        fprintf(a->tmp_f,"%s\n",str);

    a->count++;
    return 0;
}

char* _element(PARRAY a,int index)
{
    static char buf[MAXWORDS];
    int pos = 0;
    char *p=buf;
    if( index < MAXLINES )
        return a->_str[index];
    else
    {
        fseek(a->tmp_f,0L,SEEK_SET);
        while( pos < index-MAXLINES )
        {
            if( fgetc(a->tmp_f) == '\n' )
                pos++;
        }

        while( (*p = fgetc(a->tmp_f))!='\n' )
        {
            if( *p == EOF )
                break;
            p++;
        }
        *p='\0';
        return buf;
    }
}
int _destroy(PARRAY a)
{    
    fclose( a->tmp_f );
    remove(a->file_name);
    
    return 0;
}
//结构定义结束

//如果需要去掉同一文件中重复的句子则定义该宏
#define OOXX
//为了不重复打字定义的宏
#define READALL(A,F) while( 1 )\
                    {\
                        i=fgetc(F);\
                        *p=i;\
                        if( *p == '\n'||i == EOF )\
                        {\
                            *p='\0';\
                            _add(&A,line);\
                            p=line;\
                        }\
                        else\
                            p++;\
                        if( feof(F) )\
                            break;\
                    }
#define CHECK(A,B,C) for( i=0; i < A.count; i++ )\
                    {\
                        strcpy( line,_element(&A,i) );\
                        for( j=0; j<B.count; j++ )\
                        {\
                            if( !strcmp(p,_element(&B,j)) )\
                            {\
                                _add(&C,line);\
                                break;\
                            }\
                        }\
                    }
#define CHECKSELF(A,B) for( i=0;i<A.count;i++ )\
                    {\
                        strcpy(line,_element(&A,i));\
                        for( j=i+1;j<A.count;j++ )\
                        {\
                            if( !strcmp(line,_element(&A,j)) )\
                                break;\
                        }\
                        if( j== A.count )\
                            _add(&B,line);\
                    }
#define OUTTOFILE(A,F) for( i=0;i<A.count;i++ )\
                    {\
                        fprintf(F,"%s\n",_element(&A,i));\
                    }

int findDuplicateLine(const char *fina,
                      const char *finb, 
                      const char *fout)
{
    char line[MAXWORDS];
    FILE * ina,* inb,* out;
    ARRAY aa,ab,aout;
    int i,j;
#ifdef OOXX
    ARRAY tmp;
#endif
    char * p=line;
    //打开文件
    ina = fopen(fina,"r");
    inb = fopen(finb,"r");
    out = fopen(fout,"w");
    if( !ina )
        return -1; 
    if( !inb )
        return -2;
    if( !out )
        return -3;
    //初始化结构
    _init(&aa,1);
    _init(&ab,2);
    _init(&aout,3);
#ifdef OOXX
    _init(&tmp,4);
#endif
    //读数据
    READALL(aa,ina);
    READALL(ab,inb);
#ifdef OOXX //检查数据
    CHECKSELF(aa,tmp);
    CHECK(tmp,ab,aout);
#else
    CHECK(aa,ab,aout);
#endif//输出数据
    OUTTOFILE(aout,out);
    //销毁结构
    _destroy(&aa);
    _destroy(&ab);
    _destroy(&aout);
#ifdef OOXX
    _destroy(&tmp);
#endif
    //关闭文件
    fclose(ina);
    fclose(inb);
    fclose(out);
    
    return 0;
}
//测试代码
#define FINA "a.txt"
#define FINB "b.txt"
#define FOUT "c.txt"

int main(void)
{
    int flag;
    flag = findDuplicateLine(FINA,FINB,FOUT) ;
    switch(flag)
    {
    case -1:
        puts("can not open file a.");
        return -1;
    case -2:
        puts("can not open file b");
        return -1;
    case -3:
        puts("can not open file out");
        return -1;
    default:
        break;
    }
    
    return 0;
}

14 楼

#include<iostream>
using namespace std;
int min(int a,int b)
{
    if(a>b)
        return b;
    return a;
}
int fillArray(int *pArray, int h, int w)  //n is 行 
{
    int i,j,flag=0,count=1,ii,jj,k,kk;
    i=0;
    for(j=0;j<w;)
    {
        if(flag==0)
        {
            k=min(i+1,w-j);
            ii=i,jj=j;
            for(kk=0;kk<k;kk++)
            {
                pArray[ii*w+jj]=count-1+(k-kk);
                ii--;
                jj++;
            }
            count+=k;
            flag=1;
        }
        else
        {
            k=min(w-j,i+1);
            ii=i,jj=j;
            for(kk=0;kk<k;kk++)
            {
                pArray[ii*w+jj]=count;
                count++;
                ii--;
                jj++;
            }
            flag=0;
        }
        if(i!=h-1) i++;
        else j++;
    }
    return 0;
}

15 楼

第一题:
利用一个自动机,对左下运动状态,和右上运动状态,寻找下一步运动策略

[code=c]

enum STATE
{
    S_DOWN = 0x001,S_UP=0x002,S_LEFT=0x004,S_RIGHT=0x008
};



int fillArray(int *pArray, int h, int w)
{
    int s_now;
    int x=0,y=0;
    int num=1;    //要赋值的数字
    s_now=S_DOWN;
    while(x<h-1||y<w-1)
    {
        *(pArray+x*h+y)=num;
        switch (s_now)
        {
        case S_DOWN:
            x++;
            s_now=S_UP|S_RIGHT;    //第一次向下,改为向右上
            break;
        case S_LEFT|S_DOWN:
            if (x==h-1||y==0)
            {
                s_now=S_UP|S_RIGHT;
                if (x+1==h)
                    y++;
                else
                    x++;
            }else
            {
                x++;    //down
                y--;    //left
            }
            break;
        case S_UP|S_RIGHT:
            if (y==w-1||x==0)
            {
                s_now=S_LEFT|S_DOWN;
                if (y+1==w)
                    x++;
                else
                    y++;
            }else
            {
                x--;
                y++;
            }
            
            break;
        }
        num++;
    }
    *(pArray+x*h+y)=num;
    return num;
}
[/code]

16 楼

#include <iostream>
using namespace std;
int main()
{    
    int h,w,i,j;
    int Array[h][w];
    int fillArray(int *pArray, int h, int w);
    for(i=0;i<h;h++)
        for(j=0;j<w;j++)
            cout<<Array[i][j]<<endl;

}
int fillArray(int *pArray, int h, int w)
{        int n;
        int sum(int n);
        for(i=0;i<h;h++)
        for(j=0;j<w;j++)
            if(i==0;j==0) Array[i][j]=1;
            else {
                    n=i+j;
                    Array[i][j]=sum(n)+j+1;
            }
}
int sum(int n)
{
    int s,m;
    s=0;
    for(m=1;m<=n;m++)
        s=s+m;
    return s;
}

17 楼

//第一题
#include <iostream>
#include <cstdlib>
using namespace std;
int fillArray(int *pArray, int h, int w)
{
    int x = 0,y = 0;
    int count = 0;
    int num = 0;
    do
    {
        if(!num)
        {
            while(1)
            {
                pArray[y*w+x] = ++count;
                if(x-1<0||y+1>=h)
                    break;
                else
                {
                    x--;
                    y++;
                }
            }
            if(y+1>=h)
                x++;
            else
                y++;
        }
        else
        {
            while(1)
            {
                pArray[y*w+x] = ++count;
                if(x+1>=w||y-1<0)
                    break;
                else
                {
                    x++;
                    y--;
                }
            }
            if(x+1>=w)
                y++;
            else
                x++;
        }
        num^=1;
    }while(!(x==w&&y==h));
    return 0;
}

//第二题
#include <iostream>
#include <cstdio>
#include <cstdlib>
using namespace std;

class data
{
public:
       data *link[512];
       data()
       {
             for(int i = 0; i < 512; i++)
                 link[i] = 0;
       }
};
void del(data *temp)
{
     for(int i = 0; i < 512; i++)
         if(temp->link[i])
             del(temp->link[i]);
     delete temp;
     return;
}
int findDuplicateLine(const char *pszFile1, const char *pszFile2, const char *pszFileResult)
{
    data head;
    FILE *f = fopen(pszFile1,"r");
    char s[82];
    char *p;
    data *temp;
    fgets(s,82,f);
    while(s[0])
    {
        p = s;
        temp = &head;
        while(*p)
        {
            if(temp->link[*p+127]==0)
                temp->link[*p+127] = new data;
            temp = temp->link[*p+127];
            p++;
        }
        memset(s,0,sizeof(char)*82);
        fgets(s,82,f);
    }
    fclose(f);
    f = fopen(pszFile2,"r");
    FILE *f2 = fopen(pszFileResult,"w");
    fgets(s,82,f);
    while(s[0])
    {
        p = s;
        temp = &head;
        while(*p)
        {
            if(temp->link[*p+127]==0)
                break;
            temp = temp->link[*p+127];
            p++;
        }
        if(!(*p))
            fprintf(f2,"%s\n",s);
        memset(s,0,sizeof(char)*82);
        fgets(s,82,f);        
    }
    fclose(f);
    fclose(f2);
    del(&head);
    return 0;
}

18 楼

迟到了。还好没结贴。[em1][em1]
[code=c]

int fillArray(int *pArray, int h, int w)
{
    int i, j;
    int min, max, hflag;
    int start_num = 1;

    if(h < w){//height > wide
        min = h;
        max = w;
        hflag = 0;
    }
    else{
        min = w;
        max = h;
        hflag = 1;
    }

    for(i=0; i<min; i++){
        start_num += i;
        for(j=0; j<i+1; j++){
            if(i%2 == 0)//left
                pArray[(i-j)*w+j] = start_num + i - j;
            else
                pArray[(i-j)*w+j] = start_num + j;
        }
    }
    for(i=min; i<=max-1; i++){
        start_num += min;
//        printf("%d ", start_num);
        for(j=0; j<min; j++){
            if(i%2 == 0){//left
                if(hflag == 0)
                    pArray[(min-j-1)*w+i+j-min+1] = start_num + min - j - 1;
                else
                    pArray[(i-j)*w+j] = start_num + min - j - 1;
            }
            else{//right
                if(hflag == 0)
                    pArray[(min-j-1)*w+i+j-min+1] = start_num + j;
                else
                    pArray[(i-j)*w+j] = start_num + j;
            }
            
        }
    }

    for(i=max; i<max+min-1; i++){
        start_num += max-i+min;
//        printf("%d ", start_num);
        for(j=0; j<min-(i-max+1); j++)
        {
            if(i%2 == 0){//left
                if(hflag == 0)
                    pArray[(min-j-1)*w+i+j-min+1] = start_num + max + min - i - 2 - j;
                else
                    pArray[(max-1-j)*w+i-max+1+j] = start_num + min - (i -max + 1) - j - 1;
            }
            else{
                if(hflag == 0)
                    pArray[(min-j-1)*w+i+j-min+1] = start_num + j;
                else
                    pArray[(max-1-j)*w+i+j-max+1] = start_num + j;
            }
        }
    }


    return 0;
}[/code]

19 楼


#include <stdio.h>
#include <string.h>
#include <math.h>
#include <assert.h>
#include <stdlib.h>
#include <stdio.h>
#include <time.h>
#include <ctype.h>
#include <conio.h>

#define        MAXROW        65536
#define        MAXCOL        80
#define        N        20
#define        M        10

int fillArray(int *pArray, int h, int w)
{
    int        i, j;
    int        count = 0;
    int        sign = -1;
    int        start, end;
    int        row, col;
    
    for(i=0; i<h+w-1; ++i)
    {
        start = i<h?0:i-h+1;
        end   = i<w?i:w-1;
        
        if(sign > 0)
        {
            row = i<h?i:h-1;
            col = start;
        }
        else
        {
            row = i<w?0:i-w+1;
            col = end;
        }
        
        for(j=start; j<=end; ++j)
        {
            pArray[row*w+col] = ++count;
            row -= sign;
            col += sign;
        }
        
        sign = -sign;
    }
    
    return 0;
}

int GetFileLength(const char *pszFile)
{
    FILE    *fp;
    if((fp=fopen(pszFile, "rb"))==NULL)
        return -1;

    fseek(fp, 0, SEEK_END);
    long    len = ftell(fp);
    fclose(fp);

    return len;
}

int cmp(const void *x, const void *y)
{
    return strcmp(*(const char**)x, *(const char **)y);
}

template <class T>
void Swap(T &x, T &y)
{
    T    t;

    t = x;
    x = y;
    y = t;
}

char    *strs[MAXROW];

int findDuplicateLine(const char *pszFile1, const char *pszFile2, const char *pszFileResult)
{
    int        len1, len2;

    len1 = GetFileLength(pszFile1);
    len2 = GetFileLength(pszFile2);
    if(len1 > len2)
    {
        Swap(len1, len2);
        Swap(pszFile1, pszFile2);
    }

    int        count = 0;
    char    *strTemp = new char[MAXCOL];
    char    **result;
    FILE    *fp1, *fp2, *fp;

    if((fp=fopen(pszFileResult, "wt")) == NULL)
        return false;
    if((fp1=fopen(pszFile1, "rt")) == NULL)
        return false;
    if((fp2=fopen(pszFile2, "rt")) == NULL)
        return false;

    while(1)
    {
        if(fgets(strTemp, MAXCOL, fp1) == NULL)
            break;
        strs[count] = new char[MAXCOL];
        strcpy(strs[count], strTemp);
        ++count;
    }
    qsort((void*)strs, count, sizeof(char*), cmp);

    while(1)
    {
        if(fgets(strTemp, MAXCOL, fp2) == NULL)
            break;
        result = (char**)bsearch((char*)&strTemp, (char*)strs, count, sizeof(char*), cmp);
        if(result != NULL)
            fprintf(fp, "%s", *result);
    }

    fclose(fp1);
    fclose(fp2);
    fclose(fp);

    delete []strTemp;
    for(int i=0; i<count; ++i)
        delete []strs[i];

    return true;
}

20 楼

这种题目实际意义大不大

我来回复

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