主题:第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个回复)
11 楼
alloyman [专家分:690] 发布于 2008-07-05 09:08:00
学习
12 楼
alloyman [专家分:690] 发布于 2008-07-05 09:11:00
学
13 楼
ati9200pro [专家分:100] 发布于 2008-07-05 22:23:00
//第一题解法:
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 楼
shbgreenery [专家分:10] 发布于 2008-07-06 09:50:00
#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 楼
yuwg_le [专家分:20] 发布于 2008-07-06 21:14:00
第一题:
利用一个自动机,对左下运动状态,和右上运动状态,寻找下一步运动策略
[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 楼
rongyuanhua [专家分:0] 发布于 2008-07-06 22:34:00
#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 楼
hdzhyf [专家分:30] 发布于 2008-07-08 13:13:00
//第一题
#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 楼
ppc [专家分:3090] 发布于 2008-07-08 22:26:00
迟到了。还好没结贴。[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 楼
boxertony [专家分:23030] 发布于 2008-07-09 09:25:00
#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 楼
baiytao [专家分:30] 发布于 2008-07-09 11:36:00
这种题目实际意义大不大
我来回复