访问数组元素(引用)

时间限制: 1 Sec 内存限制: 128 MB

题目描述

输入n,输入n个数,计算n个数的和并输出。
假设主函数定义如下,不可修改。请补齐put函数。

输入

测试次数
每组测试数据一行,正整数n(1~1000),后跟n个整数。

输出

每组测试数据输出一行,即n个整数的和。

样例输入

3
4 10 20 30 40
10 1 2 3 -1 -2 -3 1 2 3 4
5 0 0 0 0 10

样例输出

sum=100
sum=10
sum=10

提示

解决方案

不明白这种混杂着C89和C99还有C++风格的代码有什么理由不让人改

#include <iostream>

const size_t N = 1000;

int &put(int *array, size_t size) {
    return *(array + size);
}

int main() {
    size_t T;
    std::cin >> T;
    while (T--) {
        int array[N]{};
        size_t size;
        std::cin >> size;
        for (size_t i = 0; i < size; ++i) {
            std::cin >> put(array, i);
        }
        int sum = 0;
        for (size_t i = 0; i < size; ++i) {
            sum += array[i];
        }
        std::cout << "sum=" << sum << std::endl;
    }
    return 0;
}

求最大值最小值(引用)

时间限制: 1 Sec 内存限制: 128 MB

题目描述

编写函数void find(int *num,int n,int &minIndex,int &maxIndex),求数组num(元素为num[0],num[1],…,num[n-1])中取最小值、最大值的元素下标minIndex,maxIndex(若有相同最值,取第一个出现的下标。)
输入n,动态分配n个整数空间,输入n个整数,调用该函数求数组的最小值、最大值下标。最后按样例格式输出结果。
改变函数find功能不计分。

输入

测试次数
每组测试数据一行:数据个数n,后跟n个整数

输出

每组测试数据输出两行,分别是最小值、最大值及其下标。具体格式见样例。多组测试数据之间以空行分隔。

样例输入

2
5 10 20 40 -100 0
10 23 12 -32 4 6 230 100 90 -120 15

样例输出

min=-100 minindex=3
max=40 maxindex=2

min=-120 minindex=8
max=230 maxindex=5

提示

解决方案

#include <iostream>

void find(const int *array, size_t size, size_t &min_index, size_t &max_index) {
    for (size_t i = 0; i < size; ++i) {
        if (array[min_index] > array[i]) {
            min_index = i;
        }
        if (array[max_index] < array[i]) {
            max_index = i;
        }
    }
}

int main() {
    size_t T;
    std::cin >> T;
    while (T--) {
        size_t size;
        std::cin >> size;
        int *array = new int[size];
        for (size_t i = 0; i < size; ++i) {
            std::cin >> array[i];
        }
        size_t min_index = 0, max_index = 0;
        find(array, size, min_index, max_index);
        std::cout << "min=" << array[min_index] << " minindex=" << min_index << std::endl
                  << "max=" << array[max_index] << " maxindex=" << max_index << std::endl
                  << std::endl;
    }
    return 0;
}

三数论大小(引用)

时间限制: 1 Sec 内存限制: 128 MB

题目描述

输入三个整数,然后按照从大到小的顺序输出数值。
要求:定义一个函数,无返回值,函数参数是三个整数参数的引用,例如int &a, int &b, int &c。在函数内通过引用方法来对三个参数进行排序。主函数调用这个函数进行排序。
要求:不能直接对三个整数进行排序,必须通过函数而且是引用的方法。

输入

第一行输入t表示有t个测试实例
第二行起,每行输入三个整数
输入t行

输出

每行按照从大到小的顺序输出每个实例,三个整数之间用单个空格隔开

样例输入

3
2 4 6
88 99 77
111 333 222

样例输出

6 4 2
99 88 77
333 222 111

提示

解决方案

#include <iostream>
 
void swap(int &lhs, int &rhs) {
    int tmp = lhs;
    lhs = rhs;
    rhs = tmp;
}
 
void sort(int &a, int &b, int &c) {
    if (c > b) {
        swap(c, b);
    }
    if (c > a) {
        swap(c, a);
    }
    if (b > a) {
        swap(b, a);
    }
}
 
int main() {
    size_t T;
    std::cin >> T;
    while (T--) {
        int a, b, c;
        std::cin >> a >> b >> c;
        sort(a, b, c);
        std::cout << a << ' ' << b << ' ' << c << std::endl;
    }
    return 0;
}

字符串合并(指针与函数)

时间限制: 1 Sec 内存限制: 128 MB

题目描述

定义一个函数char *strAdd(char *s1, char *s2),其返回的是s1和s2两个字符串合并后的值。(要求不能改变s1和s2)

输入

测试数据的组数 t
第一组字符串1
第一组字符串2
第二组字符串1
第二组字符串2
…….

输出

第一组字符串1 第一组字符串2 第一组字符串1和字符串2的合并
第二组字符串1 第二组字符串2 第二组字符串1和字符串2的合并
………

样例输入

2
hello
world
string
concatation

样例输出

hello world helloworld
string concatation stringconcatation

提示

解决方案

#include <iostream>
#include <cstring>

char *strcat(char *str1, char *str2) {
    size_t str1_length = strlen(str1), str2_length = strlen(str2);
    auto buffer = new char[str1_length + str2_length + 1];
    auto buffer_ptr = buffer, str1_ptr = str1, str2_ptr = str2;
    while (*str1_ptr) {
        *(buffer_ptr++) = *(str1_ptr++);
    }
    while (*str2_ptr) {
        *(buffer_ptr++) = *(str2_ptr++);
    }
    *buffer_ptr = '\0';
    return buffer;
}

int main() {
    size_t T;
    std::cin >> T;
    while (T--) {
        char str1[1024], str2[1024];
        std::cin >> str1 >> str2;
        std::cout << str1 << ' ' << str2 << ' ' << strcat(str1, str2) << std::endl;
    }
    return 0;
}

函数调用(函数指针)

时间限制: 1 Sec 内存限制: 128 MB

题目描述

定义并实现三个函数:
第一个函数是整数函数,返回类型为整数,参数是一个整数变量,操作是求该变量的平方值
第二个函数是浮点数函数,返回类型为浮点数,参数是一个浮点数变量,操作是求该变量的平方根值。求平方根可以使用函数sqrt(浮点参数),将返回该参数的平方根,在VC中需要头文件cmath。
第三个函数是字符串函数,无返回值,参数是一个字符串指针,操作是把这个字符串内所有小写字母变成大写。
要求:定义三个函数指针分别指向这三个函数,然后根据调用类型使用函数指针来调用这三个函数。不能直接调用这三个函数。
如果类型为I,则通过指针调用整数函数;如果类型为F,则通过指针调用浮点数函数;如果类型为S,则通过指针调用字符串函数

输入

第一行输入一个t表示有t个测试实例
每行先输入一个大写字母,表示调用类型,然后再输入相应的参数
依次输入t行

输出

每行输出调用函数后的结果

样例输入

5
S shenzhen
I 25
F 6.25
I 31
S China

样例输出

SHENZHEN
625
2.5
961
CHINA

提示

解决方案

#include <iostream>
#include <cmath>

int square(int number) {
    return number * number;
}

double square_root(double number) {
    return sqrt(number);
}

void to_upper_case(char *string) {
    while (char ch = *string) {
        if ('a' <= ch && ch <= 'z') {
            *string -= ('a' - 'A');
        }
        string += 1;
    }
}

int main() {
    size_t T;
    std::cin >> T;
    while (T--) {
        char type;
        std::cin >> type;
        switch (type) {
            case 'I': {
                int number;
                std::cin >> number;
                int (*function_ptr)(int) = square;
                std::cout << function_ptr(number) << std::endl;
                break;
            }
            case 'F': {
                double number;
                std::cin >> number;
                double (*function_ptr)(double) = square_root;
                std::cout << function_ptr(number) << std::endl;
                break;
            }
            case 'S': {
                char string[1024];
                std::cin >> string;
                void (*function_ptr)(char *) = to_upper_case;
                function_ptr(string);
                std::cout << string << std::endl;
                break;
            }
            default:
                exit(-1);
        }
    }
    return 0;
}

字符串比较(指针与字符)

时间限制: 1 Sec 内存限制: 128 MB

题目描述

编写一个函数比较两个字符串,参数是两个字符指针(要求显式定义,例如char *S, char *T),比较字符串S和T的大小。如果S大于T,则返回1,如果S小于T则返回-1,如果S与T相等则返回0。
比较规则:
1.把两个字符串的相同位置上的字符进行比较,字符的大小比较以ASCII值为准
2.在比较中,如果字符串S的字符大于字符串T的字符的数量超过小于的数量,则认为S大于T,如果等于则S等于T,如果小于则S小于T
例如S为aaccdd,T为eebbbb,每个位置比较得到S前两个字母都小于T,但后4个字母都大于T,最终认为S大于T
3.如果两个字符串长度不同,则更长的字符串为大
在主函数中输入两个字符串,并调用该函数进行判断,在判断函数中必须使用函数参数的指针进行字符比较

输入

输入t表示有t个测试实例
接着每两行输入两个字符串
依次输入t个实例

输出

每行输出一个实例的比较结果

样例输入

3
aaccdd
eebbbb
AAbb++
aaEE*-
zznnkk
aaaaaaa

样例输出

1
0
-1

提示

解决方案

#include <iostream>
#include <cstring>

int strcmp(char *str1, char *str2) {
    size_t str1_length = strlen(str1), str2_length = strlen(str2);
    if (str1_length > str2_length) {
        return 1;
    } else if (str1_length < str2_length) {
        return -1;
    }
    unsigned int value1 = 0, value2 = 0;
    while (*str1 != '\0') {
        if (*str1 == *str2) {
            continue;
        }
        if (*(str1++) > *(str2++)) {
            value1 += 1;
        } else {
            value2 += 1;
        }
    }
    if (value1 > value2) {
        return 1;
    } else if (value1 < value2) {
        return -1;
    } else {
        return 0;
    }
}

int main() {
    size_t T;
    std::cin >> T;
    while (T--) {
        char str1[1024], str2[1024];
        std::cin >> str1 >> str2;
        std::cout << strcmp(str1, str2) << std::endl;
    }
    return 0;
}

月份查询(指针数组)

时间限制: 1 Sec 内存限制: 128 MB

题目描述

已知每个月份的英文单词如下,要求创建一个指针数组,数组中的每个指针指向一个月份的英文字符串,要求根据输入的月份数字输出相应的英文单词
1月 January
2月 February
3月 March
4月 April
5月 May
6月 June
7月 July
8月 August
9月 September
10月 October
11月 November
12月 December

输入

第一行输入t表示t个测试实例
接着每行输入一个月份的数字
依次输入t行

输出

每行输出相应的月份的字符串,若没有这个月份的单词,输出error

样例输入

3
5
11
15

样例输出

May
November
error

提示

解决方案

#include <iostream>

int main() {
    const char *calendar[] = {"January", "February", "March",
                              "April", "May", "June",
                              "July", "August", "September",
                              "October", "November", "December"};
    size_t T;
    std::cin >> T;
    while (T--) {
        unsigned int month;
        std::cin >> month;
        if (1 <= month && month <= 12) {
            std::cout << calendar[month - 1] << std::endl;
        } else {
            std::cout << "error" << std::endl;
        }
    }
    return 0;
}

货币兑换(指针与常量)

时间限制: 1 Sec 内存限制: 128 MB

题目描述

设定以下汇率常量
美元汇率为6.2619,表示1美元兑换6.2619元人民币
欧元汇率为6.6744,表示1欧元兑换6.6744元人民币
日元汇率为0.0516,表示1元日元兑换0.0516元人民币
港币汇率为0.8065,表示1元港币币兑换0.8065元人民币
定义一个常量指针,根据需求指针指向不同的汇率,然后计算出各种货币兑换为人民币的数量
要求:不能直接使用汇率常量进行计算,必须使用常量指针,只能使用一个指针

输入

输入一个t表示有t个测试实例
每行先输入一个字母,表示货币类型,然后再输入一个数字(正浮点数),表示货币数量
D表示美元,E表示欧元,Y表示日圆,H表示港币
依次输入t行

输出

每行输出兑换后的人民币数量,保留4位小数
在C++中,输出指定精度的参考代码如下:

#include <iostream>
#include <iomanip> //必须包含这个头文件

using namespace std;

void main( )
{
  double a =3.141596;
  cout<<fixed<<setprecision(3)<<a<<endl;  //输出小数点后3位
}

样例输入

4
Y 10000
D 88.3
H 200
E 73.1

样例输出

516.0000
552.9258
161.3000
487.8986

提示

解决方案

#include <iostream>
#include <iomanip>

const double USD_CNY = 6.2619, EUR_CNY = 6.6744, JPY_CNY = 0.0516, HKD_CNY = 0.8065;

int main() {
    size_t T;
    std::cin >> T;
    const double *exchange_rate = nullptr;
    while (T--) {
        char type;
        double money;
        std::cin >> type >> money;
        switch (type) {
            case 'D':
                exchange_rate = &USD_CNY;
                break;
            case 'E':
                exchange_rate = &EUR_CNY;
                break;
            case 'Y':
                exchange_rate = &JPY_CNY;
                break;
            case 'H':
                exchange_rate = &HKD_CNY;
                break;
            default:
                exit(-1);
        }
        std::cout << std::fixed << std::setprecision(4) << (money * *exchange_rate) << std::endl;
    }
    return 0;
}

密钥加密法(指针应用)

时间限制: 1 Sec 内存限制: 128 MB

题目描述

有一种方式是使用密钥进行加密的方法,就是对明文的每个字符使用密钥上对应的密码进行加密,最终得到密文
例如明文是abcde,密钥是234,那么加密方法就是a对应密钥的2,也就是a偏移2位转化为c;明文b对应密钥的3,就是b偏移3位转化为e,同理c偏移4位转化为g。这时候密钥已经使用完,那么又重头开始使用。因此明文的d对应密钥的2,转化为f,明文的e对应密钥的3转化为h。所以明文abcde,密钥234,经过加密后得到密文是cegfh。
如果字母偏移的位数超过26个字母范围,则循环偏移,例如字母z偏移2位,就是转化为b,同理字母x偏移5位就是转化为c
要求:使用三个指针p、q、s分别指向明文、密钥和密文,然后使用指针p和q来访问每个位置的字符,进行加密得到密文存储在指针s指向的位置。
除了变量定义和输入数据,其他过程都不能使用数组下标法,必须使用三个指针来访问明文、密钥和密文。
提示:当指针q已经移动到密钥的末尾,但明文仍然没有结束,那么q就跳回密钥头

输入

第一行输入t表示有t个测试实例
第二行输入一个字符串,表示第一个实例的明文
第三行输入一个数字串,表示第一个实例的密钥
依次输入t个实例

输出

每行输出加密后的密文

样例输入

2
abcde
234
XenOS
56

样例输出

cegfh
CksUX

提示

解决方案

#include <iostream>
#include <cstring>

typedef char *string;

char addCharRegular(char ch, int index) {
    index = index - '0';
    if ('a' <= ch && ch <= 'z') {
        return ((ch - 'a') + index) % 26 + 'a';
    } else {
        return ((ch - 'A') + index) % 26 + 'A';
    }
}

int main() {
    size_t T;
    std::cin >> T;
    while (T--) {
        const auto plaintext = new char[1024], cipher = new char[1024], ciphertext = new char[1024] {};
        std::cin >> plaintext >> cipher;
        size_t plaintext_length = strlen(plaintext), cipher_length = strlen(cipher);
        auto plaintext_ptr = plaintext, cipher_ptr = cipher, ciphertext_ptr = ciphertext;
        const auto plaintext_end = plaintext + plaintext_length, cipher_end = cipher + cipher_length;
        while (plaintext_ptr != plaintext_end) {
            *(ciphertext_ptr++) = addCharRegular(*(plaintext_ptr++), *(cipher_ptr++));
            if (cipher_ptr == cipher_end) {
                cipher_ptr = cipher;
            }
        }
        *ciphertext_ptr = '\0';
        std::cout << ciphertext << std::endl;
    }
    return 0;
}

动态数组(指针与数组)

时间限制: 1 Sec  内存限制: 128 MB

题目描述

一开始未知数组长度,根据要求创建不同类型的指针,并且使用指针创建相应长度的数组,然后再完成不同的要求
若要求创建整数数组,计算数组内所有数据的平均值
若要求创建字符数组,找出数组内的最大字母
若要求创建浮点数数组,找出数组的最小值
要求程序整个过程不能使用数组下标,从数组创建、输入到搜索、比较、计算,到输出都必须使用指针
提示:使用new关键字

输入

第一行输入t表示有t个测试实例
第二行先输入一个大写字母表示数组类型,I表示整数类型,C表示字符类型,F表示浮点数类型;然后输入n表示数组长度。
第三行输入n个数据
依次输入t个实例

输出

每个根据不同的数组类型输出相应的结果

样例输入

3
C 5
A D E B C
I 6
22 55 77 33 88 55
F 4
3.1 1.9 6.5 4.8

样例输出

E
55
1.9

提示

解决方案

不明白这种要求存在的意义。它对于让学生更好地理解指针这个问题上没有任何意义,反而降低代码质量。对于这个问题,我建议你去阅读《征服C指针》之类的图书,或许对你帮助会很大。

顺便一提,*(p+5)p[5]的语法糖,也就是说,p[5]是前者的简化形式,方便输入等。因此,在这个时候甚至5[p]p[5]也是一样的,不过别写成这样。具体内容详见上述图书。

#include <iostream>

int getAverageValue(const int *array, size_t size) {
    int sum = 0;
    size_t times = size;
    while (times--) {
        sum += *(array++);
    }
    return (sum / static_cast<int>(size));
}

char getMaximumChar(const char *array, size_t size) {
    char maxChar = *array;
    while (size--) {
        if (maxChar < *array) {
            maxChar = *array;
        }
        array += 1;
    }
    return maxChar;
}

double getMinimumFloat(const double *array, size_t size) {
    double minDouble = *array;
    while (size--) {
        if (minDouble > *array) {
            minDouble = *array;
        }
        array += 1;
    }
    return minDouble;
}

template<typename T>
T *handleArray(size_t size) {
    T *array = new T[size];
    for (size_t i = 0; i < size; ++i) {
        std::cin >> *(array + i);
    }
    return array;
}

int main() {
    size_t T;
    std::cin >> T;
    while (T--) {
        char type;
        size_t size;
        std::cin >> type >> size;
        switch (type) {
            case 'I': {
                const int *array = handleArray<int>(size);
                std::cout << getAverageValue(array, size) << std::endl;
                break;
            }
            case 'C': {
                const char *array = handleArray<char>(size);
                std::cout << getMaximumChar(array, size) << std::endl;
                break;
            }
            case 'F': {
                const double *array = handleArray<double>(size);
                std::cout << getMinimumFloat(array, size) << std::endl;
                break;
            }
            default:
                exit(-1);
        }
    }
    return 0;
}