主题:第68次编程比赛题目
ckeryradish [专家分:140] 发布于 2008-06-29 12:33:00
为了让更多的人参与比赛,此次给出两个题目
最大可用内存限制为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个回复)
沙发
Mato完整版 [专家分:1270] 发布于 2008-06-29 14:16:00
第一题:
#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;
}
板凳
Chipset [专家分:16190] 发布于 2008-06-29 14:25:00
建议第二题每行不要以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 楼
Mato完整版 [专家分:1270] 发布于 2008-06-29 21:28:00
第二题:
#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 楼
rickone [专家分:15390] 发布于 2008-06-29 21:53:00
[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 楼
zhangc511 [专家分:310] 发布于 2008-06-30 22:48:00
/*
题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 楼
卧龙孔明 [专家分:240] 发布于 2008-07-02 19:55:00
第一题是曾经的noip普及组的第一题
这两题出的没有梯度。
7 楼
abc123!!! [专家分:1080] 发布于 2008-07-02 23:45:00
题目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 楼
abc123!!! [专家分:1080] 发布于 2008-07-02 23:46:00
//题目一第二部分
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 楼
abc123!!! [专家分:1080] 发布于 2008-07-02 23:49:00
题目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 楼
ww2734 [专家分:0] 发布于 2008-07-03 10:00:00
#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 ;
}
我来回复