Free考研资料 - 免费考研论坛

 找回密码
 注册
打印 上一主题 下一主题

吉林大学计算机系考研试题答案,全部上传完毕

[复制链接]
跳转到指定楼层
楼主
jilin 发表于 06-3-28 21:01:26 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
--------------------------------------------------------------------------------
作者: 飘翎     时间: 2003-7-9 14:38     标题: [原创][连载]吉林大学计算机系考研试题答案,全部上传完毕(98-2002)

到家里两天了,东西也收拾的差不多了。现在才开始有工夫静下心来将资料整理出来,希望大家不要觉得等得太久,更不要874我呀~~嘻嘻。去年的招生简章好像是7月末左右出的吧,希望今年不要有太多的变化才好。希望大家努力复习基础课,耐心等待吧。


由于我打字比较慢,因此,争取以一天一套的速度更新,希望大家不要嫌我慢哈……


复习要点:尽量多理解解题的思路,不要就题论题,尽量多举一反三。
答题方式:在答题之前能够尽量用简捷明了的语言写清楚你的思路以及你变量的用法。然后写出程序,少写程序注释以避免程序看起来比较乱。注意,思路是最重要的!!!!

2002年试题

说明: 这个据传说是02年的标准答案,是已经上机验证过的。(我也没有验证过,最近还没有重新装系统,.net近似挂掉了……!>_<!)在答题过程中,不必写出main函数,只要能够写出功能实现的函数即可。注释均为飘翎在考研复习过程中写的,如果有错误请指正,欢迎大家修改以及增加注释。
(一)
#include <stdio.h>
int a[100];

void insert(int i ,int b[])
{
  
int k;
if(i==0)   return;//递归出口,注意对异常情况的处理
if(b[i-1]>b)
{
  k=b[i-1];
  b[i-1]=b;
  b=k;
insert(i-1,b);
}

void main(void)//是用来测试用的,不是很重要,在考试过程中可以不用写的……
{
  for(i=0;i<20;i++)
   a=2*i+5;
j=10;
a[j]=20;
insert(j,a)
for(i=0;i<20;i++)
printf("%d",a);
printf("\n";
}

(二)


#include <stdio.h>

int a[100]={1,2,3,4,2,2,5};
int sublen(int a[])

{
int i,ll,lmax;
ll=1;lmax=1;
for(i=0;i<20;i++)
{
  if(a<=a[i+1])
{ll=ll+1;continue;}//记录当前递增子序列长度,否则当前递增子序列已经结束
if(lmax<ll) lmax=ll;
ll=1;//表忘了初始化
}
return lmax;
}

void main()

{
printf("\n";
printf("len=%d",sublen(a));
for(i=5;i<20;i++)//为了上机测试赋值,不必理会……
a=2*i+5;
a[0]=1;
a[4]=33;
a[6]=100;
for(i=0;i<20;i++)
printf("%d",a);
printf("\n";
printf("len=%d,sublen(a)";

}



(三)

#include <iostream.h>

typedef struct elem{
int val;
struct elem *next;
} intNode;

int member(int a, intNode *head)
{int sg=0;
intNode *p;
p=head;
while(p!=NULL)
{
if(p->val==a)
{sg=1;break;}
p=p->next;
}
return (sg);
}

intNode *SetAdd(intNode *p,intNode *q)
{

int n;intNode *r,*a,*b1,*b2;
if(!p) return q;
if(!q) return p;//特殊状况处理,采分点……
r=p;
while(p)
{a=p;
p=p->next;
}
p=r;

while(member(q->val,p))
q=q->next;
b2=q;
b1=q->next;
while(b1)
{
n=b1->next;
if(member(n,p))
b2->next=b1->next;
else b2=b1;
b1=b1->next;
}
a->next=q;
return r;
}



(四)

#include <iostream.h>

typedef struct elem{
int val;
struct elem *next;
}intNode;

intNode *inverse(intNode *head,int *n)//作用:调转指针
{
intNode *f,*g,*h;
int i=0;
if(head!=NULL)
{
f=head;
g=NULL;
while(f->next!=NULL)
{h=f;f=f->next;h->next=g;g=h;i++;}//注意指针的变化
f->next=g;
head=f;
}
*n=i+1;
return head;
}

intNode *Add88(intNode *p,intNode *q)
{
intNode *p1,*q1,*p2,*q2,*r1,*r2,*r;
int i,m,n,k,t,sg,jw;//jw为jinWei,呵呵,进位……
if(!p) return q;
if(!q) return p;
p1=inverse(p,&m);
q1=inverse(q,&n);//根据链表的特点,只有先调转,然后才能进行计算……
jw=0;
sg=1;
k=m;
if(m>n)
{sg=2,k=n;}
for(i=0;i<k;i++)
{t=p1->val+jw;
r=new intNode;
r->val=t%8;
jw=(int)(t/8);
r->next=NULL;
r1->next=r;
r1=r;
p1=p1->next;
}
if(jw){r=new intNode;r->val=jw;r->next=NULL;
r1->next=r ;}
r2=inverse(r2,&i);
}

void main() //验证程序
{
intNode *aa,*bb,*p1,*p2,*q1,*q2;
aa= new intNode;
aa->val=5;
q1=aa;
bb=new intNode;
bb->val=7;
a2=bb;

for(int i=3,i<57,i+=9)
{
p1=new intNode;
p1->val=i%8;
pq->next=NULL;
q1->next=p1;
q1=p1;}
p1=aa;
while(p1)
{cout<<p1->val<<",";
p1=p1->next;}

cout<<endl;
for(i=2;i<12;i+=3)
{p1=new intNode;p1->val=i%8;p1->next=NULL;q2->next=p1;
q2=p1;}

p1=bb;

while(p1)
{cout<<p1->val<<" ,";
p1=p1->next;}
cout <<endl<<endl;
p2=Add88(aa,bb)
p1=p2;
while(p1)
{cout<<p1->val<<" ,";

p1=p1->next;}
cout<<endl;
}


(五)

double f(double x,double y)
{l1: x=x+1.5
y=y+x;
if(y<=100) goto l1;
return y;}

double g(double x, double y )
{
s1;
s2;
if(y>100) return y;
return (g(x+1.5,x+y+1.5));

}



98年试题答案(辅导班讲义)

二。(1)解题思想:用p,q,k分别纪录A,B,C,三个数组正在访问的位置。如果,A[P]<=B[q],那么将A[P]赋给c[k].否则,将B[q]赋给

C[k].如果A先访问完,把B的剩余部分复制到C中。同样,如果B先访问完,把A的剩余部分复制到C中。
设计函数如下:

Void fun (int a[],int b[],int c[])
{
  int i,p=0,q=0,k=0;
while((p<=m-1)&&(q<=n-1))
{if(a[p]<=b[q])
{
  c[k]=a[p];
p++;}
else
{
c[k]=b[q];
q++;}
k++;
}
if(p==m)
{
for(i=q;i<=n-1;i++)
{
c[k]=b;
k++;}
}
if(q==n)
{
for(i=p;i<=n-1;i++)
{
c[k]=a;
k++;}
}
}
沙发
 楼主| jilin 发表于 06-3-28 21:01:36 | 只看该作者
(2)解题思想:从数组的第一个元素a[0]开始访问,用一个变量p来纪录当前平台的整数值,用length纪录最长平台的长度,用counter动态

纪录每一个平台的长度。如果某一个平台访问完以后counter>length则修改length.
设计函数如下:
int fun(int a[],int n)
{
int length=1,counter=1;
int p=a[0];
for(int k=1;k<n;K++)
{
   if(a[k]==p) counter++;
   else
   {p=a[k];
    if(length<counter)  length=counter;
     counter=1;
   }
}
if(length<counter)  length=counter;
return length;

}

(3)解题思想:从数组的第一个元素a[0]开始访问,每访问到一个零,则从后面找到一个非零元素与其交换。若找不到,那么程序结束。
设计函数如下:

void fun(int a[],int n)
{
int i,j,p;
for(i=0;i<n;i++)
{
  if(a==0)
  {
   for(j=i;j<n;j++)
   {
     if(a[j]!=0)
   { p=j;break;}
    if(j==n-1) return;
   }
   a=a[p];
   a[p]=0;
  }
}
}


三,解法一, 解题思想:用一个数组a[200]来存放集合的元素,并且设a[0]=1.每次都从集合中选取最小的元素输出。如果输出的数量达到

100个,则结束程序。否则产生两个数y,z,并把y,z插入到集合中去(这里插入应该按照从小到大的顺序排序,以保证每次都选取最小的元素。

)在插入的过程中还应该保证集合中没有相同的元素(集合的互异性)。
设计程序如下:


#include<iostream.h>

int a[200];
void insert(int k)
{
  int i ;
  for(i=0;i<200;i++)
   if(a==k) return;
  for(i=199;i>=0;i--)
   { if(a==0) continue;
     if(k<a) a[i+1]=a;
     else {
            a[i+1]=k; return;
          }
  }
}
  

void main()
{
   int count=0,n,i,y,z;
   a[0]=1;
   for(i=0;i<200;i++)
   {
    n=a[j];
    cout<<n<<\"  \";
    count++;
    if(count%10==0) cout<<endl;
    if(count==100)  return;
    y=2*n+1;
    z=3*n+1;
    insert(y);
    insert(z);
    }
  }
解法2,解题思想:按照自然数的顺序连续地产生数k,判断它是否属于集合M.如果是输出这个数,计数器count加一。如果不是则连续。其中

判断使用一个递归函数实现。

设计程序如下:
#include <iostream.h>
int judge(int k)
{
int t;
if(k==1) return 1;
if((k-1)%2==0&&judge((k-1)/2)) return 1;
if((k-1)%3==0&&judge((k-1)/3)) return 1;
return 0;
}

void main()
{
int k=1,count=0;
  while(count<100)
{
  if(judge(k))
   {
    cout<<k<<\"  \";
    count++
    if(count%10==0) cout<<endl;
   }
    k++;
  }
}

99年试题答案

一,(2)解题思想:平面上任意三点只要不共线,则一定能构造出一个三角形。所以只要k1=(y2-y1)/(x2-x1)和k2=(y3-y2)/(x3-x2)不相等或互为相反数就可以构成三角形。
设计函数如下:

#define  MAX 3.4e37
typedef struct
{
int x;
int y;
}PointType[100];
int Triangle(PointType Points)
{
int i,j,k,count=0;
float K1,K2;
for(i=0;i<100;i++)
  for(j=i+1;j<100;j++)
    for(k=j+1;k<100;k++)
     {
      if(Points[j].x==Points.x)
      else K1=(Points[j].y-Points.y)*1.0/(Points[j].x-Points.x);
      if(Points[j].x==Points[k].x)  K2=MAX;
      else K2=(Points[j].y-Points[k].y)*1.0/(Points[j].x-Points[k].x);
      if(K1=K2) continue;
      }
  return count;
}
      
二。解题思想:对于点N1,设它邻接到a,b,c...,那么只要求出a,b,c...,到N2的所有路径。递归地调用这个过程,就可以求出解。


设计程序如下:

#include<iostream.h>

struct node
{
int x;
struct node *next;
};
node *head;
void print()
{
   node *p=head;
   while(p!=NULL)
   {
    cout<<p->x<<\"  \";
    p=p->next;
   }
   cout<<endl;
}

void del()

{
node *p=head;
head=head->next;
delete p;
}

void insert(int i )
{
node *p=new node;
p->x=i;
p->next=head;
head=p;
}

void paths(int a[10][10],int N1,int N2)
{
if(N1==N2) {print(); return;}
for(int i=0;i<10;i++)
  if(a[N1]==1)
  {
   insert(i);
   paths(a,i,N2);
   del();
  }
}
板凳
 楼主| jilin 发表于 06-3-28 21:01:42 | 只看该作者
三,解题思想:设表l1和l2分别有m,n个元素。那么这个保序合并的过程就是把n个元素往m+1个位置插入的过程,其中插入的顺序必须保持原有的顺序。由组合数学的知识可以知道,这种插入一共有(m+n)!/m!*n!种排序方法。现在我们用一个数组c[m+1]来记录这m+1个位置的元素的个数,那么只要记录先来c[m+1]的具体数值就可以唯一确定l1 和l2的保序合并表,打印的时候只需要根据c[m+1]打印即可。
设计程序如下:


#include <iostream.h>
const int m=3;
const int n=3;
char l1[m]={\'1\',\'2\',\'3\'};
char l2[n]={\'a\',\'b\',\'c\'};

void merges(int c[],int p; int k)
{
int i,j;
if(k==n+1)
{
  print(c);
  return;
}//递归出口,如果所有的数都放完了,打印,返回
for(j=0;j<m+1;j++)
  d[j]=c[j];
c[p]=c[p]+1;//p 位置放下一个数
  k++;
for(i=p;i<m+1;i++)
{
  merge(c,i,k);
  for(j=0;j<m+1;j++)
  c[j]=d[j];
  k--;
}
}

void main()
{
int c[m+1];
int k=1;
for(int i=0;i<m+1;i++)
  c=0;
merge(c,0,k);
}

void print(int c[])

{
int sum=0,p=0;
for(int i=0;i<m+1;i++)
sum+=c;
if(sum!=n) return;
for(i=0;i<m+1;i++)
{
  for(int j=0;j<m+1;j++)
   {
    cout<<l2[p]; p++;
   }
   cout<<l1;
  }
cout<<endl;
}

四, 解题思想:按照数目的元素作为交换规则,可以得到:a[j]和a[m-1][n-1]互相交换。如果有偶数行,那么前m/2和后m/2行交换;如果有奇数行,那么第m/2的前n/2个数和后n/2个数相交换。
设计程序如下:

#include <iostream.h>

void swapt(int a[m][n])
{
   int temp ,i,j;
   for(i=0;i<(m/2);i++)
   {
    for(j=0;j<n;j++)
     {
      temp=a[j];
      a[j]=a[m-1-i][n-1-j];
      a[m-1-i][n-1-j]=temp;
     }
   }
if(m%2!=0)
{
  for(j=0;j<(n/2);j++)
   {
    temp=a[m/2][j];
    a[m/2][j]=a[m/2][n-1-j];
    a[m/2][n-1-j]=temp;
   }
}
}




2000年试题答案

一、(1)解题思想: 用5个数 a,b,c,d,e,来回替换,最终f(n)算出。

设计程序如下:

int F(int n)
{
if(n<=5) return n ;
int temp,a=1;b=2;c=3;d=4;e=5;
for(int i=6;i<=n;i++)
{
   temp=e-c-a;
   a=b;
   b=c;
   c=d;
   d=e;
   e=temp;
}
return e;
}

(2)解题思想: 根据园相切的定义: 圆心之间的距离等于半径之和或半径之差,判断一下即可。设圆心坐标和园的半径已经存在数组x[100],y[100],r[100]中。注意,相切包括内切和外切。
设计程序如下:  
#include <iostream.h>
#include <math.h>
struct node
{
int m ;
int n ;
node *next;
};
double d(int i,int j)
{
return sqrt((x-x[j])*(x-x[j])+(y-y[j])*(y-y[j]));
}

node *fun(void)
{
node *head=NULL;
node *p;
for(int i=0;i<N;i++)
  for(int j=i+1;j<N;j++)
   if((d(i,j)==r+r[j])||(d(i,j)==r-r[j])||(d(i,j)==r[j]-r))
    {
     p=new node;
     p->m=i;
     p->n=j;
     p->next=head;
     head=p;
     }
return head;
}


(3)
#include <stdio.h>

const int N=10;
int fun()
{
int i,j,k,a[N][N],b[N][N],m,s,p;
for(i=0;i<N;i++)
  for(j=0;j<N;j++)
   scanf(\"%d\",&a[j]);
for(i=0;i<N;i++)
  for(j=0;j<N;j++)
   scanf(\"%d\",&b[j]);
p=1;
for(i=0;i<N;i++)
{
  m=1;
  for(j=0;j<N;j++)
  m*=a[j];
  s=0;
  for(k=0;k<10;k++)
    s+=a[k]*b[k][k];
  p*=b*(m+s);
}
return p;
}
地板
 楼主| jilin 发表于 06-3-28 21:01:46 | 只看该作者
(4)解题思想: 根据题目要求把数组a和b扫描一次,即可求c。

#include <iostream.h>
const int m=3,n=4;
void fun(float a[],float b[],float c[])
{
float p;
p=0;
for(int k=0;k<m+n+1;k++)
{
  p=0;
  for(int i=0;i<=m;i++)
    for(int j=0;j<=n;j++)
     if(i+j==k) p+=a*b[j];
  c[k]=p;
}
}

二、解题思想:这实际上是积分过程的模拟,在区间[o,N]上,可以先划分出N个小区间,如果不能满足题目的精确度,则继续划分成2×N个区间,那么当区间个数足够多时,总可以满足精确度要求。在判断误差时,可以使用积分大和与积分小和相减的方法。
设计程序如下:

#include<iostream.h>
#include<math.h>
double function(int N,double e)
{
double s1=0,s2=10;
float M=N;
while(fabs(s2-s1)>=e)
{
  s1=0;s2=1;
   for(int i=0;i<M;i++)
  {
    s1=F(i*N/M)*N/M+s1;
    s2=F((i+1)*N/M)*N/M+s2;
   }
   N=M*2;
  }
return s1;
}

三、解题思想:用直接插入排序法进行集合的并运算,可以保证集合中没有相同的元素。其中集合元素产生时用到了函数指针。

#include <iostream.h>
typedef int(*MenuFun)(int);
int F1(int x){return x*x+1;}
int F2(int x){return 2*x*x+1;}
int F3(int x){return 3*x*x+1;}
int F4(int x){return 4*x*x+1;}
int F5(int x){return 5*x*x+1;}
int F6(int x){return 6*x*x+1;}
int F7(int x){return 7*x*x+1;}
int F8(int x){return 8*x*x+1;}
int F9(int x){return 9**x+1;}
int F10(int x){return 10*x*x+1;}

MenuFun  F[10]={F1,F2,F3,F4,F5,F6,F7,F8,F9,F10};
int sf[100];
void insert(int a)
{
for(int i=0;i<100;i++)
  if(sf==a) return;
for(i=99;i>=0;i--)
{
  if(sf==0) continue;
  if(a<sf) {sf[i+1]=sf;continue;}
  eles {sf[i+1]=a; return;}

}
}

void fun(int N)
{
int i,j,a;
sf[0]=F[0](0) ;
for(i=0;i<10;i++)
  for(j=0;j<10;j++)
   {
    a=F(i);
    insert(a);
   }
for(i=0;i<N;i++)
   cout<<sf<<\"    \";
}
四、解题思想:根据题目要求,得到寻址公式:当i>=j时,A[j]=S[i*(i+1)/2+j];当i<j时,A[j]=S[j*(j+1)/2+i].接下来再由矩阵的乘法公式即可秋初题目所需求的解。

#include <iostream.h>
const int n=5;
void fun(int s[], int x[],int y[])
{
int t,sum;
for(int i=1;i<n;i++)
  { sum=0;
    for(int j=1;j<n+1;j++)
     {
      if(i<j) t=j*(j+1)/2+i-1;
      else t=i*(i+1)/2+j-1;
       sum+=s[t]*x[j];
     }
  y=sum;
  }
}

2001年答案

二、(2)解题思想:用一个堆栈来实现递归过程。

long ack(int m,int n)
{
int a[2000],top=-1;
top++; a[top]=m;
top++; a[top]=n;
  while(top!=0)
{
  n=a[top];top--;
  m=a[top];top--;
  if(m==0) {top++;a[top]=n+1;continue;}
  if(n==0)
  {
  top++; a[top]=m-1;
  top++; a[top]=1;
  continue;
  }
top++;a[top]=m-1;
top++;a[top]=m;
top++;a[top]=n-1;
}
return a[top];
}

三、解题思想:把l1和l2两个表分别扫描一遍,把扫描得到的数对放到对偶表中。最后再把对偶表中的相同的元素删除即可。
struct node
{
char x;
char y;
node *next;
};
node *head;
void del()
{
node *p=head,*q,*r;
while(p!=NULL)
{
  q=p->next;
  r=p;
  while(q!=NULL)
  {
   if(p->x==q->x&&p->y==q->y)
     {
      r->next=q->next;  delete q; q=r->next;
     }
   else {r=q;  q=q->next;}
  }
}
}

四、解题思想:设一个方向变量orient,取值0,1,2,3分别代表往右,往下,往左,往上。当遇到边界或 当前位置已经有东西时,调整方向。否则一直顺着当前方向走。走到一个位置,把a数组的相应位置的字符写到b上。(此题还有一种解法,详见谭好强的c语言厚的那本习题)

const int n=4;
void fun(char a[][n],char b[][n])
{
int i=0,j=0,p=0,orient=0;
while(p<n*n)
{
  if(orient==0)
  {
    if(j==n||b[j]!=32)
     {
      i++;
      j--;
      orient=(orient+1)%4;
      continue;
     }
    else
     {
      b[j]=a[p/n][p%n];
      p++;
      j++;
     }
   }
  if(orient==1)
  {
   if(i==n||b[j]!=32)
    {
      i--;
      j--;
      orient=(orient+1)%4;
      continue;
    }
   else
     {
      b[j]=a[p/n][p%n];
      p++;
      i++;
     }
   }

if(orient==2)
  {
   if(j==-1||b[j]!=32)
    {
      i--;
      j++;
      orient=(orient+1)%4;
      continue;
    }
   else
     {
      b[j]=a[p/n][p%n];
      p++;
      j--;
     }
   }
if(orient==3)
  {
   if(j==n||b[j]!=32)
    {
      i++;
      j++;
      orient=(orient+1)%4;
      continue;
    }
   else
     {
      b[j]=a[p/n][p%n];
      p++;
      i--;
     }
   }
}
}
※ 修改:飘翎于2003-07-10 15:04:39修改本文
※ 修改:飘翎于2003-07-10 18:54:26修改本文
--------------------------------------------------------------------------------
5#
szy85 发表于 09-2-4 19:10:58 | 只看该作者
xiexie xinkule
6#
完成一梦 发表于 09-2-23 14:19:33 | 只看该作者
真的谢谢啦!
7#
娜艾丝 发表于 09-3-12 06:59:05 | 只看该作者
谢谢楼主 感激不尽
8#
夜半凉初透 发表于 09-10-14 16:23:42 | 只看该作者
这是复试的答案吗?
貌似是吧
打这么多实在是辛苦您了
9#
原语明天 发表于 10-4-9 18:46:55 | 只看该作者
辛苦啦~楼主童鞋
您需要登录后才可以回帖 登录 | 注册

本版积分规则

联系我们|Free考研资料 ( 苏ICP备05011575号 )

GMT+8, 24-11-27 04:57 , Processed in 0.105722 second(s), 10 queries , Gzip On, Xcache On.

Powered by Discuz! X3.2

© 2001-2013 Comsenz Inc.

快速回复 返回顶部 返回列表