一、函数题
1、vector
本题要求实现一个Vector类模板,能实现数据的存储和访问。通过[]
运算符访问时只能访问已经存在的元素,而通过add()
方法访问时可以自动扩展内部存储空间。
注意,这个Vector
的行为和std::vector
是不同的
template
class Vector {
...
#include
using namespace std;
/* 请在这里填写答案 */
int main()
{
Vector vint;
int n,m;
cin >> n >> m;
for ( int i=0; i vv = vint;
cout << vv[vv.get_size()-1] << endl;
vv.add(m);
cout << vint.get_size() << endl;
}
100 50
100
50
99
51
-1
100
代码解答:
template
class Vector
{
private:
int pos;
int size = 100;
T* data;
public:
Vector() {
pos = 0;
data = new T[size];
}
int add(T m) {
data[pos]=m;
pos++;
return pos-1;
}
int get_size() { return pos; }
void remove(int m) {
for (int i = m; i < pos-1; i++) {
data[i] = data[i + 1];
}
pos--;
}
const T& operator[](int index)const
{
return data[index];
}
};
2、二维向量相加(C++ 运算符重载)
裁判测试程序样例中展示的是一段二维向量类TDVector的定义以及二维向量求和的代码,其中缺失了部分代码,请补充完整,以保证测试程序正常运行。
提示:需要补充的函数有:
1. 带参构造函数
2. getX
3. getY
4. setX
5. setY
6. 运算符重载函数
#include
#include
using namespace std;
class TDVector{
private:
double x;
double y;
public:
TDVector(){
x = y = 0;
}
/** 你提交的代码将被嵌在这里(替换本行内容) **/
};
int main(){
TDVector a;
double x, y;
cin >> x >> y;
TDVector b(x, y);
cin >> x >> y;
TDVector c;
c.setX(x);
c.setY(y);
TDVector d;
d = a + b + c;
cout << fixed << setprecision(2) << d.getX() << ' ' << d.getY();
return 0;
}
1.1 2.2
3.3 4.4
4.40 6.60
代码解答:
TDVector(double a,double b) {
x=a,y=b;
}
void setX(double a){
x=a;
}
void setY(double b){
y=b;
}
double getX(){
return x;
}
double getY(){
return y;
}
TDVector operator+(TDVector &a){
TDVector c;
c.x = this->x + a.x;
c.y = this->y + a.y;
return c;
}
3、实现数组类(C++ 拷贝构造函数、拷贝函数)
裁判测试程序样例中展示的是一段实现“数组类”的代码,其中缺失了部分代码,请补充完整,以保证测试程序正常运行。
提示:要想程序正确运行,至少需要补充以下函数(可能还需要补充其他函数):
1. 带参构造函数
2. 拷贝构造函数
3. 拷贝函数(赋值运算符重载)
#include
using namespace std;
class ArrayIndexOutOfBoundsException{ // 异常类
public:
int index;
ArrayIndexOutOfBoundsException(int k){
index = k;
}
};
class Array{
private:
int *data;
int size;
static const int dSize = 10; // 数组默认大小
public:
Array( ){ // 无参构造
size = dSize;
data = new int[size]( );
}
/** 你提交的代码将被嵌在这里(替换本行内容) **/
int& operator [] (int k){ // 运算符 [ ] 重载,以方便数组的使用
if(k<0 || k>=size) throw ArrayIndexOutOfBoundsException(k);
return data[k];
}
friend ostream& operator << (ostream& o, const Array& a); // 运算符 << 重载,以方便输出
};
ostream& operator << (ostream& o, const Array& a){
o << '[' ;
for(int i=0; i> n >> k;
Array a(n); // 构造数组,大小为 n
for(int i=0; i
15 666
[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14]
[0,1,2,3,4,5,6,666,8,9,10,11,12,13,14]
[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14]
[0,1,2,3,4,5,6,666,8,9,10,11,12,13,14]
[0,1,2,3,4,5,6,2223,8,9,10,11,12,13,14]
代码解答:
Array(int n){
size = n;
data = new int[size]();
}
Array(const Array& a){
size = a.size;
data = new int[size]();
for (int i = 0; i < size; i++){
data[i] = a.data[i];
}
}
Array& operator=(const Array& a){//重载“=”,便于类对象的data数组赋值
if (a.size != size){
delete[]data;
size = a.size;
data = new int[size];
}
for (int i = 0; i < size; i++){
data[i] = a.data[i];
}
return *this; //this指针返回本函数本身的Array
}
~Array(){
delete[]data;//写析构函数是个好习惯,节约内存
}
4、写出派生类构造方法(C++)
裁判测试程序样例中展示的是一段定义基类People
、派生类Student
以及测试两个类的相关C++代码,其中缺失了部分代码,请补充完整,以保证测试程序正常运行。
提示:
观察类的定义和main方法中的测试代码,补全缺失的代码。
注意:真正的测试程序中使用的数据可能与样例测试程序中不同,但仅按照样例中的格式调用相关函数。
#include
using namespace std;
class People{
private:
string id;
string name;
public:
People(string id, string name){
this->id = id;
this->name = name;
}
string getId(){
return this->id;
}
string getName(){
return name;
}
};
class Student : public People{
private:
string sid;
int score;
public:
Student(string id, string name, string sid, int score)
/** 你提交的代码将被嵌在这里(替换此行) **/
}
friend ostream& operator <<(ostream &o, Student &s);
};
ostream& operator <<(ostream &o, Student &s){
o << "(Name:" << s.getName() << "; id:"
<< s.getId() << "; sid:" << s.sid
<< "; score:" << s.score << ")";
return o;
}
int main(){
Student zs("370202X", "Zhang San", "1052102", 96);
cout << zs << endl;
return 0;
}
(无)
(Name:Zhang San; id:370202X; sid:1052102; score:96)
代码解答:
: People(id,name){
this->sid = sid;
this->score = score;
}
string getsid() {
return this->sid;
}
int getscore() {
return this->score;
二、编程题
1、部分排序
对于一组数据,我们可以只对原先处在中间位置的那些元素进行排序。
在一行内输入n r a1 a2 ... an
其中,不大于200的正整数n
表示该组数据的个数;不大于200的非负整数r
表示该组数据两端各自留有r
个数不参与排序,若r+r>=n
,则该组数据无需排序。
整数a1 a2 ... an
是该组的n
个数据,且都在8位以内。
排序之后的序列,元素之间用一个空格间隔,最后一个元素之后不加空格。
5 1 6 5 4 3 2
6 3 4 5 2
代码解答:
#include
#include
using namespace std;
int main(){
int i,j,n,r,c;
cin >> n;
vector a;
cin >> r;
for(i=0; i> a0;
a.push_back(a0);
}
if(2*ra[j+1]){
c=a[j];
a[j]=a[j+1];
a[j+1]=c;
}
}
}
for(i=0; i
2、宿舍谁最高?
学校选拔篮球队员,每间宿舍最多有 4 个人。现给出宿舍列表,请找出每个宿舍最高的同学。定义一个学生类 Student,有身高 height,体重 weight 等。
首先输入一个整型数 n (1≤n≤106),表示有 n 位同学。
紧跟着 n 行输入,每一行格式为:宿舍号 name height weight
。宿舍号
的区间为 [0, 999999], name
由字母组成,长度小于 16,height
,weight
为正整数。
按宿舍号从小到大排序,输出每间宿舍身高最高的同学信息。题目保证每间宿舍只有一位身高最高的同学。
注意宿舍号不足 6 位的,要按 6 位补齐前导 0。
7
000000 Tom 175 120
000001 Jack 180 130
000001 Hale 160 140
000000 Marry 160 120
000000 Jerry 165 110
000003 ETAF 183 145
000001 Mickey 170 115
000000 Tom 175 120
000001 Jack 180 130
000003 ETAF 183 145
代码解答:
#include
#include
using namespace std;
class student
{
public:
int id;
string name;
int height;
int weight;
student(){id = -1;name = " "; height = 0; weight = 0;}
};
int main()
{
int n, maxroom = 0;
cin >> n;
student *pstu = new student[n];
for(int i = 0; i < n; i++)
{
cin >> pstu[i].id >> pstu[i].name >> pstu[i].height >> pstu[i].weight;
if(maxroom <= pstu[i].id + 1)
{
maxroom = pstu[i].id + 1;
}
}
int *p = new int [maxroom];
for(int i = 0; i < maxroom; i++)
{
p[i] = -1;
}
for(int i = 0; i < n; i++)
{
if(pstu[i].height >= pstu[p[pstu[i].id]].height)
{
p[pstu[i].id] = i;
}
}
for(int i = 0; i < maxroom; i++)
{
if(p[i] != -1)
{
cout << setfill('0') << setw(6) << i << " " << pstu[p[i]].name << " " << pstu[p[i]].height << " " << pstu[p[i]].weight << endl;
}
}
delete[] p;
delete[] pstu;
}
3、 队列操作
请实现一个MyQueue类,实现出队,入队,求队列长度.
实现入队函数 void push(int x);
实现出队函数 int pop();
实现求队列长度函数 int size();
每个输入包含1个测试用例。每个测试用例第一行给出一个正整数 n (n <= 10^6) ,接下去n行每行一个数字,表示一种操作:
1 x : 表示从队尾插入x,0<=x<=2^31-1。
2 : 表示队首元素出队。
3 : 表示求队列长度。
对于操作2,若队列为空,则输出 “Invalid”,否则请输出队首元素。 对于操作3,请输出队列长度。
每个输出项最后换行。
5
3
2
1 100
3
2
0
Invalid
1
100
代码解答:
#include
using namespace std;
#define MAXQSIZE 100
typedef struct
{
int *base;
int front;
int rear;
}SqQueue;//定义队列元素
int InitQueue(SqQueue& q)
{
q.base = new int[MAXQSIZE];
if (!q.base){
return 0;
}
q.front = 0;
q.rear = 0;
return 1;
}
int push(SqQueue& q, int x)
{
if ((q.rear + 1) % MAXQSIZE == q.front)
return 0;
q.base[q.rear] = x;
q.rear=q.rear + 1;
return 1;
}
int pop(SqQueue& q)
{
int e=0;
if (q.rear == q.front)
e=-1;
else
{
e = q.base[q.front];
q.front = q.front + 1;
}
return e;
}
int size(SqQueue& q)
{
return q.rear-q.front;
}
int main()
{
SqQueue q;
InitQueue(q);
int i, n, a, x,e;
cin >> n;
for (i = 0; i < n; i++)
{
cin >> a;
switch (a)
{
case 1:
{
cin >> x;
push(q, x);
break;
}
case 2:
{
e=pop(q);
if (e == -1)
{
cout << "Invalid" << endl;
break;
}
cout <
4、字符串排序--string类的使用
先输入你要输入的字符串的个数。然后换行输入该组字符串。每个字符串以回车结束,每个字符串不多于一百个字符。
如果在输入过程中输入的一个字符串为“stop”,也结束输入。
然后将这输入的该组字符串按每个字符串的长度,由小到大排序,按排序结果输出字符串。如果存在多个字符串长度相同,则按照原始输入顺序输出。
字符串的个数,以及该组字符串。每个字符串以‘\n’结束。如果输入字符串为“stop”,也结束输入.
可能有多组测试数据,对于每组数据,
将输入的所有字符串按长度由小到大排序输出(如果有“stop”,不输出“stop”)。
4
faeruhyytrjh tjytj
hsrthts hjnshtgfhs
stop
3
htrskbns
bsartanjsf tyjndyt
nsr jj jtey
faeruhyytrjh tjytj
hsrthts hjnshtgfhs
htrskbns
nsr jj jtey
bsartanjsf tyjndyt
提示:
根据输入的字符串个数来动态分配存储空间(采用new()函数)。每个字符串会少于100个字符。
测试数据有多组,注意使用while()循环输入。
代码解答:
#include
#include
#include
using namespace std;
typedef long long ll;
int main(){
int n;
string s;
vector v;
while(cin>>n&&n){
cin.get();
while((n--) && getline(cin,s) && s!="stop"){
v.push_back(s);
}
for(int i=0;iv[j+1].length()){
string s=v[j];
v[j]=v[j+1];
v[j+1]=s;
}
}
}
for(int i=0,n=v.size();i
5、友元函数的练习
定义Boat与Car两个类,两者都有私有的整型weight属性,定义两者的一个友元函数getTotalWeight(),计算二者的重量和。
参考主函数:
int main()
{
int n,m;
cin>>n>>m;
Boat boat(n);
Car car(m);
cout<<"船和汽车共重"<
请在这里写输入格式。例如:输入在一行中给出2个整数m和n。
请在这里描述输出格式。例如:对每一组输入,在一行中输出:船和汽车共重M+n吨值。
在这里给出一组输入。例如:
40 30
在这里给出相应的输出。例如:
船和汽车共重70吨
代码解答:
#include
using namespace std;
class Car;
class Boat{
private:
int weight;
public:
Boat(int n){
weight = n;
}
friend int getTotalWeight(Boat &b,Car &c);
};
class Car{
private:
int weight;
public:
Car(int n){
weight = n;
}
friend int getTotalWeight(Boat &b,Car &c);
};
int getTotalWeight(Boat &b,Car &c){
return b.weight+c.weight;
}
int main(){
int n,m;
cin >> n >> m;
Boat boat(n);
Car car(m);
cout<<"船和汽车共重"<
6、Disk Scheduling
Everyone knows that the files are stored in the magnetic disk. It reads the information according to the horizontal movement of the magnetic head on the track and the rotation of the magnetic disk. In order to reduce the file access time, many excellent disk scheduling algorithms have appeared.
In this problem, Shortest Seek Time First Algorithm (SSTF), which requires that the track to be accessed next is closest to the track where the current magnetic head is located. For example, given that the current magnetic head is on a track of 100, the number of tracks which need to be accessed is (55, 58, 39, 18, 90, 160, 150, 38, 184). Because 90 is the closest track to 100, the head moves to track 90 with a distance of 10 (∣100−90∣), and then finds the closest track to 90 is 58 and the distance is 32 (∣90−58∣), followed by 55 ... Finally, the resulting access sequence is (90, 58, 55, 39, 38, 18, 150, 160, 184), and the sum of the travel distances is ∣100−90∣ + ∣90−58∣ + ∣58−55∣ + ∣55−39∣ + ∣39−38∣ + ∣38−18∣ + ∣18−150∣ + ∣150−160∣ + ∣160−184∣ = 10 + 32 + 3 + 16 + 1 + 20 + 132 + 10 + 24 = 248.
Note that if there are multiple tracks with the smallest distance from the current track, the track with the smallest number will be taken as the next track.
Now given the number of the current magnetic head and the track sequence which you need to access, Little Gyro wants to calculate the sum of the magnetic head's moving distance.
Each input file only contains one test case.
The first line contains two integer n, m (1 ≤ n ≤ 106, 1 ≤ m ≤ 109), indicating the length of the track sequence and the number of the current magnetic head.
The second line contains n integers a1,a2,...,an (1 ≤ ai ≤ 109), indicating the track sequence.
For each test case output an integer indicating the sum of the magnetic head's moving distance.
9 100
55 58 39 18 90 160 150 38 184
248
Code Solution:
#include
#include
#include
#include
#include
using namespace std;
long long int a[1000005];
int main()
{
long long int n, m, left, right, s = 0;
scanf("%lld %lld", &n,&m);
for (int i = 0; i < n; i++)
scanf("%lld", &a[i]);
sort(a, a + n); //对n个数据进行排序
for (int i = 1; i < n; i++) //将m值插入进去后,获取m左边的值left与右边的值right
{
if (m <= a[0]) //特判m是否比第一个值还小
{
left = -1;
s = s + a[0] - m;
m = a[0];
right = 1;
break;
}
if (m > a[n - 1]) //特判m是否比最后一个值还大
{
right = n;
s = s + m - a[n - 1];
m = a[n - 1];
left = n - 2;
break;
}
if (m >= a[i - 1] && m <= a[i]) //遍历搜索m在n个数据中,排到哪个位置
{
long long int sl,sr;
sl = m - a[i-1];
sr = a[i] - m;
if (sl <= sr)
{
s = s + sl;
m = a[i - 1];
left = i - 2;
right = i;
break;
}
else
{
s = s + sr;
m = a[i];
left = i - 1;
right = i+1;
break;
}
}
}
while (left != -1 && right!=n) //开始左右比较,并且累加s,替换m值
{
long long int sl, sr;
sl =m-a[left];
sr = a[right]-m;
if (sl <= sr)
{
s = s + sl;
m = a[left];
left--;
}
else
{
s = s + sr;
m = a[right];
right++;
}
}
if (left == -1) //若m到达最左边后,只需不断计算右边没计算的值
{
while (right != n)
{
long long int sr;
sr = a[right]-m;
s = s + sr;
m = a[right];
right++;
}
}
if (right == n) //若m到达最右边后,只需不断计算左边没计算的值
{
while (left != -1)
{
long long int sl;
sl = m - a[left];
s = s + sl;
m = a[left];
left--;
}
}
printf("%lld\n", s);
return 0;
}