【我的青春coding物语肯定有问题!】第六次上机卡题复盘
嗨嗨!这篇是在等夜宵的时候敲的
幸好带了电脑 哈哈
怎么说呢 这次上机确实可以说是六次里面最难的,应该是模板这一部分不大熟?
我们不多说,直接看题目吧:
02 编程填空:又见模板
描述
填写代码,按要求输出结果:
#include <iostream>
#include <string>
using namespace std;
// 在此处补充你的代码
int main() {
int t;
cin >> t;
while( t -- ) {
int b1[10];
for(int i = 0;i < 10; ++i)
cin >> b1[i];
A<int, 10> a1 = b1;
cout << a1[2] << endl;
double b2[5] ;
for(int i = 0;i < 5; ++i)
cin >> b2[i];
A<double, 5> a2 = b2;
cout << a2.sum() << endl;
string b3[4] ;
for(int i = 0;i < 4; ++i)
cin >> b3[i];
A<string, 4> a3 = b3;
cout << a3.sum() << endl;
}
return 0;
}
输入
第一行是整数n,表示有n组数据
每组数据有3行
第一行是10个整数
第二行是5个小数
第三行是4个不带空格的字符串,它们之间用空格分隔
输出
先输出10个整数里面的第三个
再输出5个小数的和 (不用考虑小数点后面几位,用cout直接输出即可)
再输出4个字符串连在一起的字符串
样例输入
1
1 2 3 4 5 6 7 8 9 10
4.2 0.0 3.1 2.7 5.2
Hello , world !
样例输出
3
15.2
Hello,world!
Solution
首先我们能看到 这道题需要我们声明一个template 的模板,如果连这个都想不出来可以回去重修了
然后,观察到a1=b1 这个套路,就发现我们需要用指针的new 来写这个复制构造函数
现在 我们发现还需要一个sum函数,这里要注意的是,我们在T temp的时候要赋初值,而这个时候我们很难知道自己要赋什么初值(因为数据类型未知),所以我们直接赋成0了
下面看代码:
#include <iostream>
#include <string>
using namespace std;
template<class T,int siz>
class A{
private:
T* p;
public:
A(T* b){
p=new T[siz];
for(int i=0;i<siz;i++){
p[i]=b[i];
}
}
T operator [](int id){
return p[id];
}
T sum(){
T temp=p[0];
for(int i=1;i<siz;i++){
temp+=p[i];
}
return temp;
}
};
int main() {
int t;
cin >> t;
while( t -- ) {
int b1[10];
for(int i = 0;i < 10; ++i)
cin >> b1[i];
A<int, 10> a1 = b1;
cout << a1[2] << endl;
double b2[5] ;
for(int i = 0;i < 5; ++i)
cin >> b2[i];
A<double, 5> a2 = b2;
cout << a2.sum() << endl;
string b3[4] ;
for(int i = 0;i < 4; ++i)
cin >> b3[i];
A<string, 4> a3 = b3;
cout << a3.sum() << endl;
}
return 0;
}
05 编程填空:很眼熟的模板题
描述
填写代码,按要求输出结果
#include <cstdio>
#include <iostream>
#include <string>
#include <cstring>
using namespace std;
// 在此处补充你的代码
string int2string(int x) { return to_string(x); }
int int2squareint(int x) { return x * x; }
int string2int(string str) {
int res = 0;
for (string::iterator iter = str.begin(); iter != str.end(); ++iter)
res += *iter;
return res;
}
string string2longerstring(string str) { return str + str; }
int main() {
int t;
cin >> t;
while (t--) {
int b1[10];
for (int i = 0; i < 10; ++i)
cin >> b1[i];
A<int, 10> a1 = b1;
cout << a1.sum(2, 6, int2squareint) << endl;
cout << a1.sum(2, 6, int2string) << endl;
string b2[4];
for (int i = 0; i < 4; ++i)
cin >> b2[i];
A<string, 4> a2 = b2;
cout << a2.sum(0, 3, string2int) << endl;
cout << a2.sum(0, 3, string2longerstring) << endl;
}
return 0;
}
输入
第一行是整数n,表示有n组数据
每组数据有2行
第一行是10个整数
第二行是4个不带空格的字符串,它们之间用空格分隔
输出
先输出10个整数里面的第3个到第7个的平方和
再输出10个整数里从第3个到第7个,按照字符串的方式,顺序连接的结果
再输出4个字符串里,第1个到第4个串中,所有字符的ASCII码加和得到的整数
再输出4个字符串里,第1个到第4个串,分别复制一遍后,按照字符串的方式,顺序连接的结果。
样例输入
1
1 2 3 4 5 6 7 8 9 10
Machine , Learning !
样例输出
135
34567
1586
MachineMachine,,LearningLearning!!
提示
3^2 + 4^2 + 5^2 + 6^2 + 7^2 = 135
“Machine,Learning!”中所有字符的ASCII码相加为1586
Solution
我们看到复制,还是先知道这个方式,然后我要讲的是这个sum函数的定义方式
我们用模板套模板的方式,定义,这样就一目了然了
下面看代码:
#include <cstdio>
#include <iostream>
#include <string>
#include <cstring>
using namespace std;
template<class T,int siz>
class A{
private:
T* p;
public:
A(T* b){
p=new T[siz];
for(int i=0;i<siz;i++){
p[i]=b[i];
}
}
template<class T1,class T2>
T1 sum(int x,int y,T1 f(T2 k)){
T1 temp=f(p[x]);
for(int i=x+1;i<=y;i++){
temp+=f(p[i]);
}
return temp;
}
};
string int2string(int x) { return to_string(x); }
int int2squareint(int x) { return x * x; }
int string2int(string str) {
int res = 0;
for (string::iterator iter = str.begin(); iter != str.end(); ++iter)
res += *iter;
return res;
}
string string2longerstring(string str) { return str + str; }
int main() {
int t;
cin >> t;
while (t--) {
int b1[10];
for (int i = 0; i < 10; ++i)
cin >> b1[i];
A<int, 10> a1 = b1;
cout << a1.sum(2, 6, int2squareint) << endl;
cout << a1.sum(2, 6, int2string) << endl;
string b2[4];
for (int i = 0; i < 4; ++i)
cin >> b2[i];
A<string, 4> a2 = b2;
cout << a2.sum(0, 3, string2int) << endl;
cout << a2.sum(0, 3, string2longerstring) << endl;
}
return 0;
}
07:很难蒙混过关的CArray3D三维数组模板类
描述
实现一个三维数组模版CArray3D,可以用来生成元素为任意类型变量的三维数组,输出指定结果
#include <iostream>
#include <iomanip>
#include <cstring>
using namespace std;
template <class T>
class CArray3D
{
// 在此处补充你的代码
};
CArray3D<int> a(3,4,5);
CArray3D<double> b(3,2,2);
void PrintA()
{
for(int i = 0;i < 3; ++i) {
cout << "layer " << i << ":" << endl;
for(int j = 0; j < 4; ++j) {
for(int k = 0; k < 5; ++k)
cout << a[i][j][k] << "," ;
cout << endl;
}
}
}
void PrintB()
{
for(int i = 0;i < 3; ++i) {
cout << "layer " << i << ":" << endl;
for(int j = 0; j < 2; ++j) {
for(int k = 0; k < 2; ++k)
cout << b[i][j][k] << "," ;
cout << endl;
}
}
}
int main()
{
int No = 0;
for( int i = 0; i < 3; ++ i ) {
a[i];
for( int j = 0; j < 4; ++j ) {
a[j][i];
for( int k = 0; k < 5; ++k )
a[i][j][k] = No ++;
a[j][i][i];
}
}
PrintA();
memset(a[1],-1 ,20*sizeof(int));
memset(a[1],-1 ,20*sizeof(int));
PrintA();
memset(a[1][1],0 ,5*sizeof(int));
PrintA();
for( int i = 0; i < 3; ++ i )
for( int j = 0; j < 2; ++j )
for( int k = 0; k < 2; ++k )
b[i][j][k] = 10.0/(i+j+k+1);
PrintB();
int n = a[0][1][2];
double f = b[0][1][1];
cout << "****" << endl;
cout << n << "," << f << endl;
return 0;
}
输入
无
输出
等同于样例
样例输入
无
样例输出
layer 0:
0,1,2,3,4,
5,6,7,8,9,
10,11,12,13,14,
15,16,17,18,19,
layer 1:
20,21,22,23,24,
25,26,27,28,29,
30,31,32,33,34,
35,36,37,38,39,
layer 2:
40,41,42,43,44,
45,46,47,48,49,
50,51,52,53,54,
55,56,57,58,59,
layer 0:
0,1,2,3,4,
5,6,7,8,9,
10,11,12,13,14,
15,16,17,18,19,
layer 1:
-1,-1,-1,-1,-1,
-1,-1,-1,-1,-1,
-1,-1,-1,-1,-1,
-1,-1,-1,-1,-1,
layer 2:
40,41,42,43,44,
45,46,47,48,49,
50,51,52,53,54,
55,56,57,58,59,
layer 0:
0,1,2,3,4,
5,6,7,8,9,
10,11,12,13,14,
15,16,17,18,19,
layer 1:
-1,-1,-1,-1,-1,
0,0,0,0,0,
-1,-1,-1,-1,-1,
-1,-1,-1,-1,-1,
layer 2:
40,41,42,43,44,
45,46,47,48,49,
50,51,52,53,54,
55,56,57,58,59,
layer 0:
10,5,
5,3.33333,
layer 1:
5,3.33333,
3.33333,2.5,
layer 2:
3.33333,2.5,
2.5,2,
****
7,3.33333
提示
建议做法:
- a[i][j][k] 这个表达式的第一个[]返回一个内部类的对象,该内部类也重载了[],且返回值为指针。
- 必要时需重载对象到指针的强制类型转换运算符
Solution
这题是重头戏!
感觉跟我之前写的那个,二元数组的实现有点像,这里我主要解释一下吧
首先肯定要有三维的数据和一个T* 指针,分配出[xyz]大小的空间
然后,考虑降维
我们肯定要重载[]这个函数,而根据题目提示,最后一个[]直接从T类变成T类了,所以只要在三维和二维各自重载一个[]就好
然后,为什么要写这个operator T呢?
我们为了迎合memset,要把CArray2D这个类转换成T* 类,从而完成任务!
下面看代码:
#include <iostream>
#include <iomanip>
#include <cstring>
using namespace std;
template <class T>
class CArray3D
{
public:
int x,y,z;
T* p;
CArray3D(int x,int y,int z):x(x),y(y),z(z){
p=new T[x*y*z];
}
class CArray2D{
private:
T* dd;
int k;
public:
CArray2D(T* pd,int id):dd(pd),k(id){ }
T* operator [](int index){
T* ddg=dd+index*k;
return ddg;
}
operator T*(){
return dd;
}
};
CArray2D operator [](int index){
T* dd=p+index*y*z;
return CArray2D(dd,z);
}
};
CArray3D<int> a(3,4,5);
CArray3D<double> b(3,2,2);
void PrintA()
{
for(int i = 0;i < 3; ++i) {
cout << "layer " << i << ":" << endl;
for(int j = 0; j < 4; ++j) {
for(int k = 0; k < 5; ++k)
cout << a[i][j][k] << "," ;
cout << endl;
}
}
}
void PrintB()
{
for(int i = 0;i < 3; ++i) {
cout << "layer " << i << ":" << endl;
for(int j = 0; j < 2; ++j) {
for(int k = 0; k < 2; ++k)
cout << b[i][j][k] << "," ;
cout << endl;
}
}
}
int main()
{
int No = 0;
for( int i = 0; i < 3; ++ i ) {
a[i];
for( int j = 0; j < 4; ++j ) {
a[j][i];
for( int k = 0; k < 5; ++k )
a[i][j][k] = No ++;
a[j][i][i];
}
}
PrintA();
memset(a[1],-1 ,20*sizeof(int));
memset(a[1],-1 ,20*sizeof(int));
PrintA();
memset(a[1][1],0 ,5*sizeof(int));
PrintA();
for( int i = 0; i < 3; ++ i )
for( int j = 0; j < 2; ++j )
for( int k = 0; k < 2; ++k )
b[i][j][k] = 10.0/(i+j+k+1);
PrintB();
int n = a[0][1][2];
double f = b[0][1][1];
cout << "****" << endl;
cout << n << "," << f << endl;
return 0;
}
10.简单的整数类
描述
输入两个数 m,n( 0<=m,n <= 9),输出它们的乘积
#include <stdio.h>
#include <iostream>
using namespace std;
class MyNum{
public:
char C;
MyNum(char c='0'): C(c) {}
// 在此处补充你的代码
};
int main() {
char m,n;
cin >> m >> n;
MyNum n1(m), n2(n);
MyNum n3;
n3 = n1*n2;
cout << int(n3) << endl;
return 0;
}
输入
两个数,m,n,确保乘积小于10
输出
它们的乘积
样例输入
3 2
样例输出
6
Solution
这题的关键点在于,要想到,当超出9的范围的时候,要用什么表示
而这个在MyNum这个复制构造函数的缺省项中已经写得很明白了,就是跟'0'这个字符有关
于是解题思路就很明朗了
但是,我们还要看,这里有个明显的类型转换函数标志,就是cout这边的int
再补上,大功告成!
#include <stdio.h>
#include <iostream>
using namespace std;
class MyNum{
public:
char C;
MyNum(char c='0'): C(c) {}
MyNum operator *(const MyNum &s){
int x=C-'0';
int y=s.C-'0';
int d=x*y;
MyNum k;
k.C='0'+d;
return k;
}
operator int(){
return C-'0';
}
};
int main() {
char m,n;
cin >> m >> n;
MyNum n1(m), n2(n);
MyNum n3;
n3 = n1*n2;
cout << int(n3) << endl;
return 0;
}
大半夜的我还在写博客,今天真的手敲断了
看看这个金发双马尾傲娇x

路人女主的ED还蛮好听的,有种初恋青涩酸酸甜甜的感觉,也不知道我能不能追回来,明天继续干巴爹吧
大家可以忽略深夜乱打的这段结尾
后半学期,也请各位继续关注:
《我的青春线代物语果然有问题》
《高数女主养成计划》
《程设の旅》
《青春猪头少年不会梦到多智能体吃豆人》
《某Linux的开源软件》
还有——
《我的算法竞赛不可能这么可爱》
本期到此结束!

浙公网安备 33010602011771号