回 帖 发 新 帖 刷新版面

主题:第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个回复)

沙发

第一题:
#include "stdio.h"

int fillArray(int *pArray, int h, int w);

int main(void)
{
    int array[10000];
    int h,w,i,j;
    scanf("%d%d",&h,&w);

    fillArray(array, h, w);

    for(i=1;i<=h;i++)
    {
        for(j=1;j<=w;j++)
            printf("%4d",array[(i-1)*w+j]);
        if(w!=20)printf("\n");
    }
    getch();
    return 0;
}

int fillArray(int *pArray, int h, int w)
{
    int xx=-1, yy=1, x=0, y=0, i, t;

    for(i=1;i<=h*w;i++)
    {
        x+=xx; y+=yy;
        if(x<1||x>h||y<1||y>w){t=xx;xx=yy;yy=t;}
        if(x>h){x=h;y+=2;}
        if(y>w){y=w;x+=2;}
        if(x<1) x=1;
        if(y<1) y=1;
        pArray[(x-1)*w+y]=i;
    }
    return 0;
}

板凳

建议第二题每行不要以80个字符作为限制,还有,应该说明是文本文件或者二进制文件,再加一个条件: 内存充足。


我再给补充一个题目作为第3题吧,有兴趣的朋友可以尝试一下。

有一个100M的文本文件,现在要求最多消耗的内存空间不得超过1M,对该文件进行排序。

参考:一般而言,10秒以下(CPU: PIII 1.13GHz, RAM: PC133, Hard Drive: 4200rpm, 2MB memory)。

参赛者程序时间短者获胜。


再来一个第4题吧,有兴趣的朋友可以试一试: 内存充足,有一大批记录(就当整数吧),循环右移i位(i是下标,是个不小于0的随机数),最坏情况下,时间复杂度O(n), 空间复杂度O(1)。

参考:测试1亿个整数,循环右移1千万位,时间3秒以下(CPU: PIII 1.13GHz, RAM: PC133)。

参赛者程序时间短者获胜。

3 楼

第二题:
#include"stdio.h"
#include"string.h"
#define MAXLENGTH 81

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

typedef struct LLnode
{
    char text[MAXLENGTH];
    struct LLnode *next;
}LL;

LL *txs[256];
LL *tail[256];
FILE *file1, *file2, *result;
char temp[MAXLENGTH];

int main(void)
{
    char fLine[MAXLENGTH];
    int asc,findOut,i;
    LL *pt, *pt2;

    file1=fopen("file1.txt", "r");
    file2=fopen("file2.txt", "r");
    remove("fileResult.txt");
    result=fopen("fileR.txt", "a");

    while(!feof(file1))
    {
        fgets(fLine, MAXLENGTH, file1);
        if(feof(file1))
          strcpy(temp,fLine);
        else strncpy(temp, fLine, strlen(fLine)-1);
        strcpy(fLine,temp);
        asc=*fLine;
        pt=(LL*)malloc(sizeof(LL));
        strcpy(pt->text, fLine);
        if(tail[asc]==NULL)
        {
            txs[asc]=pt;
            tail[asc]=pt;
        }
        else
        {
            tail[asc]->next=pt;
            tail[asc]=pt;
        }
    }
    for(i=0;i<=255;i++)tail[i]->next->next=NULL;
    while(!feof(file2))
    {
        fgets(fLine, MAXLENGTH, file2);
        if(feof(file2))
          strcpy(temp,fLine);
        else strncpy(temp, fLine, strlen(fLine)-1);
        strcpy(fLine,temp);
        asc=*fLine;
        pt=txs[asc]->next;
        findOut=0;
        while((pt!=NULL)&&(!findOut))
        {
            if(strcmp(pt->text, fLine)==0)
            {
                findDuplicateLine(fLine, fLine, fLine);
                findOut=1;
            }
            pt=pt->next;
        }
    }
    rename("fileR.txt","fileResult.txt");
    getch();
    return 0;
}

int findDuplicateLine(
    const char *pszFile1,
    const char *pszFile2,
    const char *pszFileResult
)
{
    fputs(strcat(pszFileResult,"\n"),result);
    return 0;
}

4 楼

[code=c]
#include <cstdlib>
#include <iostream>

using namespace std;

enum dir_type{up,down};

int fillArray(int *pArray, int h, int w)
{
    int i=0,j=0;//当前位置 第i行 第j列 
    dir_type dir=down;//当前方向
    int n=1;//当前填的数字
    const int max = h*w;
    while(n<=max)
    {
        pArray[i*w+j]=n++;//填数 
        if(dir==up)
        {
            if(i>0 && j+1<w)//一般情况 
            {
                i--;
                j++;
                continue;
            }
            if(j+1==w)//到达右边
            {
                i++;
            }
            else// if(i==0)//到达上边
            {
                j++;
            }
            dir=down;
        }
        else //dir==down
        {
            if(j>0 && i+1<h)//一般情况 
            {
                i++;
                j--;
                continue;
            }
            if(i+1==h)//到达下边
            {
                j++;
            }
            else// if(j==0)//到达左边
            {
                i++;
            }
            dir=up;
        }
    }
    return 0; 
}

//#define TMP
template<bool,typename,typename>
struct IfThenElse;

template<typename A,typename B>
struct IfThenElse<true,A,B>
{
    typedef A result_type;
};

template<typename A,typename B>
struct IfThenElse<false,A,B>
{
    typedef B result_type;
};

template<int i,int j,int h,int w,dir_type dir,int n>
struct snake_array_generator
{
    explicit snake_array_generator(int *arr): snake(arr)
    {
        arr[i*w+j]=n;
    }
    typedef typename IfThenElse<n<h*w,
        typename IfThenElse<dir==up,
            typename IfThenElse<(i>0&&j+1<w),
                snake_array_generator<i-1,j+1,h,w,up,n+1>,
                typename IfThenElse<j+1==w,
                    snake_array_generator<i+1,j,h,w,down,n+1>,
                    snake_array_generator<i,j+1,h,w,down,n+1>
                >::result_type
            >::result_type,
            typename IfThenElse<(j>0&&i+1<h),
                snake_array_generator<i+1,j-1,h,w,down,n+1>,
                typename IfThenElse<i+1==h,
                    snake_array_generator<i,j+1,h,w,up,n+1>,
                    snake_array_generator<i+1,j,h,w,up,n+1>
                >::result_type
            >::result_type
        >::result_type,
        int*
    >::result_type snake_type;
    snake_type snake;
};

template<int N,int M>
int fillArray(int (&a)[N][M])
{
#ifndef TMP
    return fillArray(a[0],N,M);
#else
    snake_array_generator<0,0,N,M,down,1> s(a[0]);
    return 0;
#endif
}

int main(int argc, char *argv[])
{
    #define Test(N,M) { \
    int a[N][M]; \
    printf("Test Case N=%d M=%d\n",N,M); \
    fillArray(a); \
    for(int i=0;i<N;++i) \
    { \
        for(int j=0;j<M;++j) \
        { \
            printf("%3d",a[i][j]); \
        } \
        printf("\n"); \
    } }
    Test(1,1);
    Test(1,10);
    Test(10,1);
    Test(3,4);
    Test(4,3);
    Test(9,7);
    
    system("PAUSE");
    return EXIT_SUCCESS;
}
[/code]

如果能改成这个接口:
template<int N,int M>
int fillArray(int (&a)[N][M]);
才能使用另外一个。。。

5 楼

/*
题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)
*/
#include <stdio.h>
#include <conio.h> 
int fillArray(int *,int ,int); 
int main()
{
    int a[9][7];
    fillArray(&a[0][0],9,7);
    for(int i=0;i<9;i++)
    {
      for(int j=0;j<7;j++)
              printf("%3d",a[i][j]); 
      printf("\n"); 
    } 
     getch();
     return 1; 

int fillArray(int *pArray,int h,int w) 
{
    int k,i,j;
    int flag=1; 
    int flag1=1; 
    int count=h*w;
    i=j=0;
    for(k=1;k<=count;k++)
    {
      *(pArray+i*w+j)=k;
      if(i==h-1&&j==w-1)break; 
      else if((j==0&&i<h-1||j==w-1)&&flag1==1)
             {
              flag1=0; 
              i++;
              if(j==0)flag=1;
              else flag=0;
              } 
      else if((i==0&&j<w-1||i==h-1)&&flag1==1)
             {
              flag1=0; 
              j++;
              if(i==0)flag=0;
              else flag=1;
              } 
      else if(flag==1)
             {i--;j++;flag1=1;}
           else 
             {i++;j--;flag1=1;} 
    } 
    return 1; 
}

期待第二题答案
我一直对文件的EOF搞不清,不知什么时候、什么位置判断,有哪本书对这个介绍清楚的,请推荐

6 楼

第一题是曾经的noip普及组的第一题
这两题出的没有梯度。

7 楼

题目1
使用语言:C
文件包括头文件  assert.h  stdio.h  stdlib.h

//贴子分了几部分, 麻烦!
//题目一第一部分
int fillpArray(int *pArray, int h, int w) {
    assert(h > 0 && w > 0);
    pArray[0] = 1;
    
    //特化
    if(w == 1 && h == 1) {
         return 1;
    }
    //特化
    if(w == 1 && h != 1) {
         for(int i = 2; i <= h; i++)
                 pArray[i - 1] = i;
         return 1;
    }
    //特化
    if(w != 1 && h == 1) {
         for(int i = 2; i <= w; i++)
                 pArray[i - 1] = i;
         return 1;
    }
    
    int  i = 0;
    int  j = 1;
    long sum = 3;
    bool notexit;
    const long sum1 = h * w + 1;
    pArray[1 * w] = 2;
    
    for(;;) {
            notexit = true;
            for(int col = 0; notexit; ++col) {
                    pArray[w * (i - col) + j + col] = sum;
                    ++sum;
                    
                    if(i - col == 0 && j + col == w - 1 && (float)(w % 2) != 0.0f) {
                         pArray[w * (i - col) + j + col + 1] = sum;
                         ++sum;
                         i = i - col + 1;
                         j = j + col;
                         notexit = false;
                    }
                    else if(i - col == 0 && j + col == w - 1 && (float)(w % 2) == 0.0f) {
                         pArray[w * (i - col + 1) + j + col] = sum;
                         ++sum;
                         i = i - col + 2;
                         j = j + col - 1;
                         notexit = false;
                    }
                    else if(i - col == 0) {
                         pArray[w * (i - col) + j + col + 1] = sum;
                         ++sum;
                         i = i - col + 1;
                         j = j + col;
                         notexit = false;
                    }
                    else if(j + col == w - 1) {
                         pArray[w * (i - col + 1) + j + col] = sum;
                         ++sum;
                         i = i - col + 2;
                         j = j + col - 1;
                         notexit = false;
                    }
                    if(sum == sum1) {      
                         return 1;
                    }
            }

8 楼

//题目一第二部分

            
            notexit = true;
            for(int col = 0; notexit; ++col) {
                  pArray[w * (i + col) + j - col] = sum;
                  ++sum;
                  
                  if(i + col == h - 1 && j - col == 0 && (float)(h % 2) != 0.0f) {
                       pArray[w * (i + col) + j - col + 1] = sum;
                       ++sum;
                       i = i + col - 1;
                       j = j - col + 2;
                       notexit = false;
                  }
                  else if(i + col == h - 1 && j - col == 0 && (float)(h % 2) == 0.0f) {
                       pArray[w * (i + col + 1) + j - col] = sum;
                       ++sum;
                       i = i + col;
                       j = j - col + 1;
                       notexit = false;
                  }
                  else if(i + col == h - 1) {
                       pArray[w * (i + col) + j - col + 1] = sum;
                       ++sum;
                       i = i + col - 1;
                       j = j - col + 2;
                       notexit = false;
                  }     
                  else if(j - col == 0) {
                       pArray[w * (i + col + 1) + j - col] = sum;
                       ++sum;
                       i = i + col;
                       j = j - col + 1;
                       notexit = false;
                  }
                  if(sum == sum1) {
                         return 1;
                  }
            }
    }
}

9 楼

题目2
使用语言:C++
头文件    iostream  fstream  string  list
名字空间  std

int findDuplicateLine(const char *pszFile1, 
                                 const char *pszFile2, 
                                       const char *pszFileResult) {                    
    ifstream in1(pszFile1, ios::in);
    if(!in1) {
             cerr << "Error opening pszFile1" << endl;
             return 0;
    }
    ifstream in2(pszFile2, ios::in);
    if(!in2) {
             cerr << "Error opening pszFile2" << endl;
             return 0;
    }
    ofstream out(pszFileResult, ios::out);
    if(!out) {
             cerr << "Error opening pszFileResult" << endl;
             return 0;
    }
    
    list<string> s1;
    list<string> s2;
    char buffer[180];  //80 * 2 = 160
    buffer[179] = '\0';
    
    while(!in1.eof()) {
    in1.getline(buffer, 180);
    s1.push_back(string(buffer));
    }
    while(!in2.eof()) {
    in2.getline(buffer, 180);
    s2.push_back(string(buffer));
    }
    
    list<string>::iterator it1;
    list<string>::iterator it2;
    for(it1 = s1.begin(); it1 != s1.end(); it1++)
            for(it2 = s2.begin(); it2 != s2.end(); it2++)
                    if(*it1 == *it2)
                           out << *it1 << endl;
    return 1;
}

2题目均通过DEV的编译, 因为不能搞附件, 只能传函数了....
麻烦, 得分开传...

10 楼

#include<stdio.h>
#define SIZE 4

void fun(int a[SIZE][SIZE],int h,int s)
{
    int i=0,j=0,sum=h+s;
    int count,count1;
    static int t=0;
    for(count=0;count<sum;count++)
    {    i=0;j=0;
        if(count<h)
        {
            count1=count;
    
            if(count%2==1)
            {
            for(i=count1,j=count1-i;i<=count1&&j<=count1&&i>=0&&j>=0;i--,j++)
                {
                    a[i][j]=t++;
                }
        
            }
    
            if(count%2==0)
            {
                for(j=count1,i=count1-j;i<=count1&&j<=count1&&i>=0&&j>=0;i++,j--)
                    a[i][j]=t++;
            }
        }
        else
        {
            count1=h-1;

            if(count%2==1)
            {
                for(i=count1,j=count-i;i<=count1&&j<=count1&&i>=0&&j>=0;i--,j++)
                {
                    a[i][j]=t++;    
                }
        
            }
    
            if(count%2==0)
            {
                for(j=count1,i=count-j;i<=count1&&j<=count1&&i>=0&&j>=0;i++,j--)
                    a[i][j]=t++;
            }
        }
    }

    
}
void main()
{
    int i,j;
    int a[SIZE][SIZE];
    fun(a,SIZE,SIZE);
    for(i=0;i<SIZE;i++)
    {
        for(j=0;j<SIZE;j++)
            printf("%d\t",a[i][j]);
        printf("\n");
    }

    return ;
}

我来回复

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