全国大学生计算机技能应用(2020年)——C++科目决赛程序设计题解

       早上10点,准时开始比赛。10:00~11:30一个半小时的时间,需要解答13道不定项选择题、2道程序填空题、1道程序设计题和1道综合应用题。这里准备记录分享一下我的思路和解法。
       我毫不犹豫地选择先完成后面4道程序题目,如果在难度中上等的情况下,很显然,这段时间感觉是比较紧迫的。另外,我们知道编程需要充足的时间去思考分析问题,打好程序代码后还需要debug,所以我一上来跳到程序题目。下面我将对完成的这4道题目进行思路介绍和代码分析,欢迎一起学习讨论。
阶乘和、迷宫游戏属于算法设计分析方面,单链表&指针偏向数据结构,而这个类就是单纯的C++编程问题。

阶乘和(递归算法)

众所周知,阶乘的计算使用递归的方法的很经典的做法,而计算阶乘和,很容易想到的就是:在一个for循环里面,每次循环递归求解,再把此次结果相加,得到n轮之和。
如下:
设n=3,sum=0;
第一轮1!
第二轮2!
第三轮3!
sum=1!+2!+3!
而比赛题目并非我们使用的循环+递归的做法,而是需要编写2个函数实现完全递归的做法。

//函数getnumber
int getnumber(int n)
{
   int sum;
   if(n ==1)
   { 
	 	sum = 1;
	    return sum;//填空1
   }
   else
   {
       sum = getnumber(n-1)*n; //填空2
       return sum;
   }
 
}

通过getnumber函数可知,它实现了一个数阶乘的递归算法,是经典的方法。

//函数get
int get(int n){

      int sum;
      if(n==0)
	  {
          return 0;//填空3
      }
	  else
	  {
           sum = get(n-1)+getnumber(n);//填空4
      }
      return sum;
}

另外,get函数也使用了递归方式求和,首先,调用getnumber求得n的阶乘,其次,递归调用自身来求和,sum = get(n-1)+getnumber(n);巧妙地实现。由此看来,函数体功能很清晰,递归终止条件也很显然,可以说,题目换了一种求解方式,使用了“完全递归”方法来实现阶乘和。
完整程序如下:

#include<iostream>
using namespace std; 
int getnumber(int n)//递归求n的阶乘
{
   int sum;
   if(n ==1)
   { 
	 	sum = 1;
	    return sum;
   }
   else
   {
       sum = getnumber(n-1)*n; 
       return sum;
   }
 
}


int get(int n){//递归求n的阶乘和

      int sum;
      if(n==0)
	  {
          return 0;
      }
	  else
	  {
           sum =get(n-1)+getnumber(n);
      }
      return sum;
}

int main()
{

	int a;
	cout<<"请输入需要求的阶乘数:\n";
	cin>>a;
	cout<<"程序输出结果是:"<<get(a)<<endl;
	return 0;
}

学生成绩(单链表&指针)

此题目单链表包含头结点和头指针,考察结点之间的联系和指针的指向,单链表的基本操作:创建链表、初始化、插入结点、遍历单链表。只需要熟悉单链表结构和基本操作就能够正确完成。注释比较详细,完整代码如下:

#include<iostream>
#include<string>
using namespace std;
#define MAX 100

typedef struct
{
	int id;
	char name[12];
	char sex[4];
	int age;
	char door[10];
	int tel;
	int chinese;
	int math;
	int english;
	int cpri;
}Student;


typedef struct sqlist
{
	Student data;
	struct sqlist *next;

}sqlist,*Linklist;


//初始化
void init(Linklist &L)
{
	L=new sqlist;
	if(!L)
	{
		cout<<"单链表初始化失败"<<endl;
	}
	else 
	{		
		cout<<"单链表初始化成功"<<endl;
		L->next=NULL;//填空① 头结点相关操作。
	}

}
//单链表增加元素(尾插法) 
void create(Linklist &L) 
{
	int n;
	cout<<"请输入班级人数"<<endl;
	cin>>n;
	Linklist p,tail;
	tail=L;
	cout<<"请输入学号,姓名,性别,年龄,宿舍号,手机号码,语文,数学,英语成绩,c++成绩"<<endl;
	for(int i=1;i<=n;i++)
	{
		p = new sqlist;//填空②生成内存空间,不要使用malloc生成,使用new函数
		cin>>p->data.id>>p->data.name>>p->data.sex>>p->data.age>>p->data.door>>p->data.tel>>p->data.chinese>>p->data.math>>p->data.english>>p->data.cpri;
		tail->next=p;//填空③节点指向操作,插入结点p后尾指针指向修改 
		tail=p;// 尾指针重新指向新的插入p 
	}
	tail->next=NULL;//填空④尾节点的相关操作
}
//输出单链表元素
void print(Linklist L)
{
	Linklist p;
	p=L->next;
	while(p!=NULL)
	{
		cout<<p->data.id<<"  "<<p->data.name<<"  "<<p->data.sex<<"  "<<p->data.age<<"  "<<p->data.door<<"  "<<p->data.tel<<"  "<<p->data.chinese<<"  "<<p->data.english<<"  "<<p->data.cpri;
		cout<<endl;
		p=p->next;//指向下一个结点 
	
	}
}
int main()
{
	Linklist L;
	init(L);
	create(L);
	cout<<endl;
	print(L);
}

类的编写(继承&纯虚函数)

定义一个基类,包含radius(可表示边长、半径)和2个纯虚函数(求体积和表面积),要求编写正方体,圆柱体,球体类并实现其基本功能和属性,输出程序。
基本知识:

  1. C++中,把基类中没有给出具体实现的函数定义为出纯虚函数。格式如:virtual double surface_area()=0;
  2. 含有纯虚函数的类成为抽象类,所以上面所说的基类是抽象类,需要在派生类中实现具体方法。
  3. 抽象类只能做派生类的基类。不能定义抽象类的对象。

此题目实现的是编写通用函数,使用基类统一接口实现派生类的具体方法。详见代码:

#include <iostream>
using namespace std;
#define X 3.1416
class container{
protected:
		  	double radius;
public:
	container(double ra)
	{
	    		radius=ra;
	}
	virtual double surface_area()=0;      //纯虚函数,求面积。
	virtual double volume()=0;            //纯虚函数,求体积。
};

/*
	  在下方构造编写正方体,圆柱体,球体类并实现其基本功能和属性,输出程序
*/
class cube:public container//继承基类,实现纯虚函数的具体方法 
{
	public:
		cube(double ra=0):container(ra)
		{}
		virtual double surface_area()
		{
			return radius*radius*6;
		}
		virtual double volume()
		{
			return radius*radius*radius;
		}
};

class sphere:public container
{
	public:
		sphere(double ra=0):container(ra)
		{}
		virtual double surface_area()
		{
			return 4*X*radius*radius;
		}
		virtual double volume()
		{
			return 4/3*X*radius*radius*radius;
		}
};

class cylinder:public container
{
	protected:double h;
	
	public:
		cylinder(double ra=0,double b=0):container(ra)
		{
			h=b;
		}
		virtual double surface_area()
		{
			return 4*X*radius*radius+2*X*radius*h;
		}
		virtual double volume()
		{
			return X*radius*radius*h;
		}
};

int main()
{
	container *p;             //定义抽象类指针p
	cube obj1(10);            //创建正方体对象obj1
	sphere obj2(6);            //创建球体对象obj2
	cylinder obj3(4,5);        //创建圆柱体对象obj3
	p=&obj1;                  //指针p指向正方体对象obj1
	cout<<"程序输出结果:"<<endl;
	cout<<"   正方体表面积:"<<p->surface_area()<<endl;
	cout<<"   正方体体积:  "<<p->volume()<<endl;
	p=&obj2;                   //指针p指向球体对象obj2
	cout<<"   球体的表面积:"<<p->surface_area()<<endl;
	cout<<"   球体的体积:  "<<p->volume()<<endl;
	p=&obj3;                    //指针p指向圆柱体对象obj3
	cout<<"   圆体的表面积:"<<p->surface_area()<<endl;
	cout<<"   圆体的体积:  "<<p->volume()<<endl;
	return 0;
}

迷宫游戏(回溯递归)

迷宫游戏就是常见的迷宫问题,这也是这次比赛难度较大的一个题目,之前没有接触过这个迷宫问题,做起来费劲一些。

迷宫问题作为一个经典的算法题目,使用到回溯法进行求解,我想再另起一篇详细介绍迷宫游戏题目以及回溯法的具体内容,由此也复习一下之前算法设计分析的经典算法,迷宫游戏也让我意识到学习过的算法的重要性,需要不断练习,重温经典算法,才能够真正掌握,更新之后会在此放文章链接,烦请期待,与大家共勉!
迷宫游戏题解请看我的这篇博客:有趣的迷宫问题(游戏)——递归回溯算法详解

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

陆海潘江小C

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值