PTA寒假基础题训练(含解题思路)(中)

目录

 7-19 两个有序单链表求差集

AC代码:

7-20 统计数字字符和空格

AC代码:

7-21 打印沙漏

AC代码:

7-22 Wifi密码

AC代码:

7-23 福到了

AC代码:

7-24 高空坠球

AC代码:

7-25 数字三角形

AC代码:

7-26 说反话-加强版

AC代码:

7-27 输出GPLT

AC代码:

7-28 梅森数

AC代码:

7-29 找完数

AC代码:

7-30 装箱问题

AC代码:

7-31 查找满足条件的所有整数

AC代码:

7-32 数组元素循环右移问题

AC代码:

7-33 螺旋方阵

AC代码:

7-34 吃火锅

AC代码:

7-35 复数四则运算

AC代码:


因题集题目较多,另外两部分题集请移步这里:

PTA寒假基础题训练(含解题思路)(上)_清晨喝碗粥的博客-CSDN博客

PTA寒假基础题训练(含解题思路)(下)_清晨喝碗粥的博客-CSDN博客

 7-19 两个有序单链表求差集

各依次输入递增有序若干个不超过100的整数,分别建立两个递增有序单链表,分别表示集合A和集合B。设计算法求出两个集合A和B 的差集(即仅由在A中出现而不在B中出现的元素所构成的集合),并存放于A链表中。要求结果链表仍使用原来两个链表的存储空间, 不另外占用其它的存储空间。然后输出求的差集的单链表。测试数据保证结果链表至少存在一个元素。

输入格式:

首先输入一个整数T,表示测试数据的组数,然后是T组测试数据。每组测试数据先在第一行输入数据个数n及n个依次递增有序的不超过100的整数,再在第二行输入数据个数m及m个依次递增有序的不超过100的整数。

输出格式:

对于每组测试,输出A与B的差集的单链表,每两个数据之间留一个空格。

输入样例:

2
11 10 14 23 25 26 31 34 42 51 65 90
10 10 41 42 46 51 58 59 60 68 97
5 1 2 3 4 5
3 3 4 5

输出样例:

14 23 25 26 31 34 65 90
1 2

思路:题干隐隐想表达是想让学生利用链表知识进行解决,但对于算法竞赛而言,这种题一般不会出现,若真出现,秉持有轮子为何要造轮子的原则,优先利用简单的方案进行解决,所以这里我采用的是vector数组加上set容器进行判重处理,而对于普通练习可以尝试用题干要求去尝试,这里提供一个思路,可以优先利用两个指针分别指向两个单链表的头部结点,然后对这两个结点所存储的value进行判断,若一方的值小于另一方,则将值小的那一方的指针指向它所在单链表的后面一个结点,若在判断的过程中原本值小的那一方的value大于另一方时,则将指针先指向另一条链表的指针所指向的部位,然后在进行判断即可,因为题干要求求差集,所以如果两个指针所指向的value值相等,则依次按照原链表向后走一位即可(后者方法可能比较难理解,可以依据样例进行模拟思考) 

AC代码:

#include<bits/stdc++.h>
using namespace std;
int main()
{
    int i, j, k, n, m;
    cin >> n;
    vector<vector<int>>res;
    for (i = 0; i < n; i++) {
        cin >> m;
        vector<int>nums1(m, 0);
        for (j = 0; j < m; j++) {
            cin >> nums1[j];
        }
        cin >> m;
        set<int>st;
        for (j = 0; j < m; j++) {
            int x;
            cin >> x;
            st.insert(x);
        }
        vector<int>v;
        for (j = 0; j < nums1.size(); j++) {
            if (!st.count(nums1[j]))
                v.push_back(nums1[j]);
        }
        res.push_back(v);
    }
    for (i = 0; i < res.size(); i++) {
        for (j = 0; j < res[i].size(); j++) {
            if (j == 0)
                cout << res[i][j];
            else
                cout << " " << res[i][j];
        }
        cout << endl;
    }

    system("pause");
    return 0;
}

7-20 统计数字字符和空格

本题要求编写程序,输入一行字符,统计其中数字字符、空格和其他字符的个数。建议使用switch语句编写。

输入格式:

输入在一行中给出若干字符,最后一个回车表示输入结束,不算在内。

输出格式:

在一行内按照

blank = 空格个数, digit = 数字字符个数, other = 其他字符个数

的格式输出。请注意,等号的左右各有一个空格,逗号后有一个空格。 

输入样例:

Reold 12 or 45T

输出样例:

blank = 3, digit = 4, other = 8

思路:按照题意进行模拟即可 

AC代码:

#include<bits/stdc++.h>
using namespace std;
int main()
{
    int i, j, k, n, blank = 0, digit = 0, other = 0;
    char x;
    string s = "";
    while ((x = getchar()) != '\n') {
        s += x;
    }
    for (i = 0; i < s.length(); i++) {
        if (s[i] == ' ')
            blank++;
        else if (s[i] >= '0' && s[i] <= '9')
            digit++;
        else
            other++;
    }
    printf("blank = %d, digit = %d, other = %d", blank, digit, other);

    system("pause");
    return 0;
}

7-21 打印沙漏

本题要求你写个程序把给定的符号打印成沙漏的形状。

所谓“沙漏形状”,是指每行输出奇数个符号;各行符号中心对齐;相邻两行符号数差2;符号数先从大到小顺序递减到1,再从小到大顺序递增;首尾符号数相等。

给定任意N个符号,不一定能正好组成一个沙漏。要求打印出的沙漏能用掉尽可能多的符号。

输入格式:

输入在一行给出1个正整数N(≤1000)和一个符号,中间以空格分隔。

输出格式:

首先打印出由给定符号组成的最大的沙漏形状,最后在一行中输出剩下没用掉的符号数。

输入样例:

19 *

输出样例:

*****
 ***
  *
 ***
*****
2

思路:此题类似于打印菱形的加强版,这里可以优先计算好输入数字所能打的最大沙漏所需字符数,然后根据所需字符数进行找规律打印即可 

AC代码:

#include<bits/stdc++.h>
using namespace std;
int main()
{
    int i, j, k, n, num = 1, line, count = 0;
    char op;
    cin >> n;
    getchar();
    cin >> op;
    for (i = 1; num < n; i = i + 2) {
        num += (i + 2) * 2;
    }
    line = i - 2;
    for (i = 0; i < line / 2; i++) {
        for (j = 0; j < i; j++) {
            cout << ' ';
        }
        for (j = 0; j < line - 2 * i ; j++) {
            cout << op;
            count++;
        }
        cout << endl;
    }
    for (i = 0; i < line / 2 + 1; i++) {
        for (j = 0; j < line / 2 - i; j++) {
            cout << ' ';
        }
        for (j = 0; j < i * 2 + 1; j++) {
            cout << op;
            count++;
        }
        cout << endl;
    }
    cout << n - count << endl;

    system("pause");
    return 0;
}

7-22 Wifi密码

下面是微博上流传的一张照片:“各位亲爱的同学们,鉴于大家有时需要使用 wifi,又怕耽误亲们的学习,现将 wifi 密码设置为下列数学题答案:A-1;B-2;C-3;D-4;请同学们自己作答,每两日一换。谢谢合作!!~”—— 老师们为了促进学生学习也是拼了…… 本题就要求你写程序把一系列题目的答案按照卷子上给出的对应关系翻译成 wifi 的密码。这里简单假设每道选择题都有 4 个选项,有且只有 1 个正确答案。

输入格式:

输入第一行给出一个正整数 N(≤ 100),随后 N 行,每行按照 编号-答案 的格式给出一道题的 4 个选项,T 表示正确选项,F 表示错误选项。选项间用空格分隔。

输出格式:

在一行中输出 wifi 密码。

输入样例:

8
A-T B-F C-F D-F
C-T B-F A-F D-F
A-F D-F C-F B-T
B-T A-F C-F D-F
B-F D-T A-F C-F
A-T C-F B-F D-F
D-T B-F C-F A-F
C-T A-F B-F D-F

输出样例:

13224143

思路:利用哈希表存储答案,对每一行进行遍历查找答案即可 

AC代码:

#include<bits/stdc++.h>
using namespace std;
map<char, char>mp = {{'A', '1'}, {'B', '2'}, {'C', '3'}, {'D', '4'}};
int main()
{
    int i, j, k, n;
    cin >> n;
    vector<vector<string>>nums(n, vector<string>(4, ""));
    string s = "";
    for (i = 0; i < n; i++) {
        for (j = 0; j < 4; j++) {
            cin >> nums[i][j];
            if (nums[i][j][2] == 'T')
                s += nums[i][j][0];
        }
    }
    for (i = 0; i < s.length(); i++) {
        s[i] = mp[s[i]];
    }
    cout << s << endl;

    system("pause");
    return 0;
}

7-23 福到了

“福”字倒着贴,寓意“福到”。不论到底算不算民俗,本题且请你编写程序,把各种汉字倒过来输出。这里要处理的每个汉字是由一个 N × N 的网格组成的,网格中的元素或者为字符 @ 或者为空格。而倒过来的汉字所用的字符由裁判指定。

输入格式:

输入在第一行中给出倒过来的汉字所用的字符、以及网格的规模 N (不超过100的正整数),其间以 1 个空格分隔;随后 N 行,每行给出 N 个字符,或者为 @ 或者为空格。

输出格式:

输出倒置的网格,如样例所示。但是,如果这个字正过来倒过去是一样的,就先输出bu yong dao le,然后再用输入指定的字符将其输出。

输入样例1:

$ 9
 @  @@@@@
@@@  @@@ 
 @   @ @ 
@@@  @@@ 
@@@ @@@@@
@@@ @ @ @
@@@ @@@@@
 @  @ @ @
 @  @@@@@

输出样例1:

$$$$$  $ 
$ $ $  $ 
$$$$$ $$$
$ $ $ $$$
$$$$$ $$$
 $$$  $$$
 $ $   $ 
 $$$  $$$
$$$$$  $ 

输入样例2:

& 3
@@@
 @ 
@@@

输出样例2:

bu yong dao le
&&&
 & 
&&&

思路:颠倒后的图像与颠倒前的图像呈中心对称,我们可以先将其上下颠倒,然后再左右颠倒即可得到颠倒后的图像,最后将呈现图像的字符进行替换即可 

AC代码:

#include<bits/stdc++.h>
using namespace std;
int main()
{
    int i, j, k, n;
    char op;
    bool flag = true;
    cin >> op >> n;
    getchar();
    vector<string>nums(n, "");
    vector<string>item(n, "");
    for (i = 0; i < n; i++) {
        char * ch = new char [200];
        cin.getline(ch, 200, '\n');
        item[i] = nums[i] = ch;
    }
    for (j = 0; j < n; j++) {
        i = 0, k = n - 1;
        while (i < k) {
            swap(nums[i][j], nums[k][j]);
            i++;
            k--;
        }
    }
    for (i = 0; i < n; i++) {
        reverse(nums[i].begin(), nums[i].end());
    }
    for (i = 0; i < n; i++) {
        if (nums[i] != item[i])
            flag = false;
        for (j = 0; j < n; j++) {
            if (nums[i][j] != ' ')
                nums[i][j] = op;
        }
    }
    if (flag)
        cout << "bu yong dao le" << endl;
    for (i = 0; i < n; i++) {
        cout << nums[i] << endl;
    }

    system("pause");
    return 0;
}

7-24 高空坠球

皮球从某给定高度自由落下,触地后反弹到原高度的一半,再落下,再反弹,……,如此反复。问皮球在第n次落地时,在空中一共经过多少距离?第n次反弹的高度是多少?

输入格式:

输入在一行中给出两个非负整数,分别是皮球的初始高度和n,均在长整型范围内。

输出格式:

在一行中顺序输出皮球第n次落地时在空中经过的距离、以及第n次反弹的高度,其间以一个空格分隔,保留一位小数。题目保证计算结果不超过双精度范围。

输入样例:

33 5

输出样例:

94.9 1.0

思路:题不算难,根据题意模拟即可,这里最后一个测试点需要注意一下是n等于0的时候,所以需要优先进行判断 

AC代码:

#include<bits/stdc++.h>
using namespace std;
int main()
{
    long long i, j, k, n;
    double height, sum = 0;
    cin >> height >> n ;
    if (n == 0) {
        printf("0.0 0.0");
        return 0;
    }
    for (i = 0; i < n; i++) {
        sum += height + height * 1.0 / 2;
        height = height * 1.0 / 2;
    }
    sum -= height;
    printf("%.1lf %.1lf", sum, height);

    system("pause");
    return 0;
}

7-25 数字三角形

给出n,请输出一个直角边长度是n的数字直角三角形。所有数字都是 2 位组成的,如果没有 2 位则加上前导 0。

输入格式:

输入为一个正整数n,1≤n≤100。

输出格式:

输出为直角边长度是n的数字直角三角形,所有数字都是 2 位组成的,如果没有 2 位则加上前导 0,且当数字超过20时,重新从1开始。

输入样例:

5

输出样例:

1514100901
13110802
120703
0604
05

思路:此题类似于螺旋矩阵,我们可以控制二维数组的下标i和j进行模拟即可 

AC代码:

#include<bits/stdc++.h>
using namespace std;
int main()
{
    int i, j, k, n, item = 1;
    cin >> n;
    vector<vector<int>>nums(n, vector<int>(n, 0));
    i = 0, j = n - 1;
    while (1) {
        if (i == 0 && j == 0) break;
        while (j >= 0) {
            nums[i++][j--] = item;
            item++;
            item = item > 20 ? 1 : item;
        }
        j++;
        i -= 2;
        if (i == 0 && j == 0) break;
        while (i >= 0) {
            nums[i--][j++] = item;
            item++;
            item = item > 20 ? 1 : item;
        }
        i++;
        j -= 2;
    }
    nums[i][j] = item;
    for (i = 0; i < n; i++) {
        for (j = 0; j < n - i; j++) {
            printf("%02d", nums[i][j]);
        }
        cout << endl;
    }


    system("pause");
    return 0;
}

7-26 说反话-加强版

给定一句英语,要求你编写程序,将句中所有单词的顺序颠倒输出。

输入格式:

测试输入包含一个测试用例,在一行内给出总长度不超过500 000的字符串。字符串由若干单词和若干空格组成,其中单词是由英文字母(大小写有区分)组成的字符串,单词之间用若干个空格分开。

输出格式:

每个测试用例的输出占一行,输出倒序后的句子,并且保证单词间只有1个空格。

输入样例:

Hello World   Here I Come

输出样例:

Come I Here World Hello

思路:根据C++标准输入流的特性,利用字符串数组挨个进行保存,最后反转输出即可 

AC代码:

#include<bits/stdc++.h>
using namespace std;
int main()
{
    int i, j, k, n;
    string x;
    vector<string>nums;
    while (cin >> x) {
        nums.push_back(x);
    }
    reverse(nums.begin(), nums.end());
    for (i = 0; i < nums.size(); i++) {
        if (i == 0)
            cout << nums[i];
        else
            cout << " " << nums[i];
    }

    system("pause");
    return 0;
}

7-27 输出GPLT

给定一个长度不超过10000的、仅由英文字母构成的字符串。请将字符重新调整顺序,按GPLTGPLT....这样的顺序输出,并忽略其它字符。当然,四种字符(不区分大小写)的个数不一定是一样多的,若某种字符已经输出完,则余下的字符仍按GPLT的顺序打印,直到所有字符都被输出。

输入格式:

输入在一行中给出一个长度不超过10000的、仅由英文字母构成的非空字符串。

输出格式:

在一行中按题目要求输出排序后的字符串。题目保证输出非空。

输入样例:

pcTclnGloRgLrtLhgljkLhGFauPewSKgt

输出样例:

GPLTGPLTGLTGLGLL

思路:利用数组或哈希表对GPLT的每一位进行存储,然后在循环中不断遍历此数组或哈希表,直到每个字母的个数都为零为止 

AC代码:

#include<bits/stdc++.h>
using namespace std;
unordered_map<char, int>mp = {{'G', 0}, {'P', 0}, {'L', 0}, {'T', 0}};
int main()
{
    int i, j, k, n;
    string s;
    cin >> s;
    for (i = 0; i < s.length(); i++) {
        if (s[i] == 'g' || s[i] == 'G')
            mp['G']++;
        else if (s[i] == 'p' || s[i] == 'P')
            mp['P']++;
        else if (s[i] == 'l' || s[i] == 'L')
            mp['L']++;
        else if (s[i] == 't' || s[i] == 'T')
            mp['T']++;
    }
    while (1) {
        if (mp['G'] != 0) {
            cout << 'G';
            mp['G']--;
        }
        if (mp['P'] != 0) {
            cout << 'P';
            mp['P']--;
        }
        if (mp['L'] != 0) {
            cout << 'L';
            mp['L']--;
        }
        if (mp['T'] != 0) {
            cout << 'T';
            mp['T']--;
        }
        if (!mp['G'] && !mp['P'] && !mp['L'] && !mp['T']) break;
    }

    system("pause");
    return 0;
}

7-28 梅森数

形如2n−1的素数称为梅森数(Mersenne Number)。例如22−1=3、23−1=7都是梅森数。1722年,双目失明的瑞士数学大师欧拉证明了231−1=2147483647是一个素数,堪称当时世界上“已知最大素数”的一个记录。

本题要求编写程序,对任一正整数n(n<20),输出所有不超过2n−1的梅森数。

输入格式:

输入在一行中给出正整数n(n<20)。

输出格式:

按从小到大的顺序输出所有不超过2n−1的梅森数,每行一个。如果完全没有,则输出“None”。

输入样例:

6

输出样例:

3
7
31

思路:对小于等于n的每一个2^n -1 依次进行判断是否为素数即可 

AC代码:

#include<bits/stdc++.h>
using namespace std;
bool Is_prime (int n) {
    if (n == 0 || n == 1) return false;
    if (n == 2) return true;
    int item = sqrt(n) + 1;
    for (int i = 2; i <= item; i++) {
        if (n % i == 0) return false;
    }
    return true;
}
int main()
{
    int i, j, k, n;
    cin >> n;
    vector<int>res;
    for (i = 1; i <= n; i++) {
        int item = pow(2, i) - 1;
        if (Is_prime(item))
            res.push_back(item);
    }
    if (res.size() == 0)
        cout << "None" << endl;
    else {
        for (i = 0; i < res.size(); i++) {
            cout << res[i] << endl;
        }
    }

    system("pause");
    return 0;
}

7-29 找完数

所谓完数就是该数恰好等于除自身外的因子之和。例如:6=1+2+3,其中1、2、3为6的因子。本题要求编写程序,找出任意两正整数m和n之间的所有完数。

输入格式:

输入在一行中给出2个正整数m和n(1<m≤n≤10000),中间以空格分隔。

输出格式:

逐行输出给定范围内每个完数的因子累加形式的分解式,每个完数占一行,格式为“完数 = 因子1 + 因子2 + ... + 因子k”,其中完数和因子均按递增顺序给出。若区间内没有完数,则输出“None”。

输入样例:

2 30

输出样例:

6 = 1 + 2 + 3
28 = 1 + 2 + 4 + 7 + 14

思路:寻找每个数的因子,最后进行判断是否是完数,最后整体输出即可 

AC代码:

#include<bits/stdc++.h>
using namespace std;
vector<int> Is_perfect (int n) {
    int i, sum = 0;
    vector<int>res;
    for (i = 1; i < n; i++) {
        if (n % i == 0) {
            sum += i;
            res.push_back(i);
        }
    }
    if (sum == n) return res;
    res.clear();
    return res;
}
int main()
{
    int i, j, k, n, m;
    bool flag = false;
    cin >> n >> m;
    for (i = n; i <= m; i++) {
        vector<int>res;
        res = Is_perfect(i);
        if (res.size() != 0) {
            flag = true;
            cout << i << " = ";
            for (j = 0; j < res.size(); j++) {
                if (j == 0)
                    cout << res[j];
                else    
                    cout << " + " << res[j];
            }
            cout << endl;
        }
    }
    if (!flag)
        cout << "None" << endl;

    system("pause");
    return 0;
}

7-30 装箱问题

假设有N项物品,大小分别为s1​、s2​、…、si​、…、sN​,其中si​为满足1≤si​≤100的整数。要把这些物品装入到容量为100的一批箱子(序号1-N)中。装箱方法是:对每项物品, 顺序扫描箱子,把该物品放入足以能够容下它的第一个箱子中。请写一个程序模拟这种装箱过程,并输出每个物品所在的箱子序号,以及放置全部物品所需的箱子数目。

输入格式:

输入第一行给出物品个数N(≤1000);第二行给出N个正整数si​(1≤si​≤100,表示第i项物品的大小)。

输出格式:

按照输入顺序输出每个物品的大小及其所在的箱子序号,每个物品占1行,最后一行输出所需的箱子数目。

输入样例:

8
60 70 80 90 30 40 10 20

输出样例:

60 1
70 2
80 3
90 4
30 1
40 5
10 1
20 2
5

思路:每项物品顺序遍历箱子,然后进行判断,如果能装下则标记编号,否则查看下一个箱子这里记录编号可以另开一个数组,也可以采用对组(pair)的形式 

AC代码:

#include<bits/stdc++.h>
using namespace std;
int main()
{
    int i, j, k, n;
    cin >> n;
    vector<int>item(n, 100);
    vector<pair<int, int>>nums(n, pair<int, int>(0, 0));
    for (i = 0; i < n; i++) {
        cin >> nums[i].first;
        for (j = 0; j < n; j++) {
            if (item[j] >= nums[i].first) {
                nums[i].second = j + 1;
                item[j] -= nums[i].first;
                break;
            }
        }
    }
    int count = 0;
    for (i = 0; i < n; i++) {
        cout << nums[i].first << " " << nums[i].second << endl;
        if (item[i] != 100)
            count++;
    }
    cout << count << endl;

    system("pause");
    return 0;
}

7-31 查找满足条件的所有整数

本题要求编写程序,将输入的n个整数存入数组a中,然后在数组a中查找给定的x。如果数组a中的元素与x的值相同,输出所有满足条件的元素的下标(下标从0开始);如果没有找到,输出“Not Found”。

输入格式:

第1行输入一个正整数n(0<n≤10)和一个整数x,第2行输入n个整数,其间以空格分隔。题目保证数据不超过长整型整数的范围。

输出格式:

如果找到,输出所有与x的值相同的元素的下标,每行输出一个下标;如果没有找到,在一行中输出“Not Found”。

输入样例1:

5 9
2 9 8 1 9

输出样例1:

1
4

输入样例2:

10 101
2 8 10 1 9 8 -101  0  98762  1

输出样例2:

Not Found

思路:简单模拟题,依据题意模拟即可

AC代码:

#include<bits/stdc++.h>
using namespace std;
int main()
{
    int i, j, k, n, x;
    cin >> n >> x;
    vector<int>nums(n, 0);
    vector<int>res;
    for (i = 0; i < n; i++) {
        cin >> nums[i];
        if (nums[i] == x)
            res.push_back(i);
    }
    if (res.size() == 0) {
        cout << "Not Found" << endl;
    } else {
        for (i = 0; i < res.size(); i++) {
            cout << res[i] << endl;
        }
    }


    system("pause");
    return 0;
}

7-32 数组元素循环右移问题

一个数组A中存有N(>0)个整数,在不允许使用另外数组的前提下,将每个整数循环向右移M(≥0)个位置,即将A中的数据由(A0​A1​⋯AN−1​)变换为(AN−M​⋯AN−1​A0​A1​⋯AN−M−1​)(最后M个数循环移至最前面的M个位置)。如果需要考虑程序移动数据的次数尽量少,要如何设计移动的方法?

输入格式:

每个输入包含一个测试用例,第1行输入N(1≤N≤100)和M(≥0);第2行输入N个整数,之间用空格分隔。

输出格式:

在一行中输出循环右移M位以后的整数序列,之间用空格分隔,序列结尾不能有多余空格。

输入样例:

6 2
1 2 3 4 5 6

输出样例:

5 6 1 2 3 4

思路:此类题一般不会出现于算法竞赛,若真出现,对于算法竞赛,我们秉持有轮子为什么要造轮子的原则,有简单方法为什么用难方法呢?所以就另起一个数组进行保存处理,对于平时练习,我提供一个思路,题干要求不能开另一个数组,所以就要在原本的数组上下手,所以可以把原本数组的空间长度开大一点就好转移了 

AC代码:

#include<bits/stdc++.h>
using namespace std;
int main()
{
    int i, j, k, n, m;
    cin >> n >> m;
    vector<int>nums(n, 0);
    vector<int>res;
    m = m % n;
    for (i = 0; i < n; i++) {
        cin >> nums[i];
    }
    for (i = n - m; i < n; i++) {
        res.push_back(nums[i]);
    }
    for (i = 0; i < n - m; i++) {
        res.push_back(nums[i]);
    }
    for (i = 0; i < res.size(); i++) {
        if (i == 0)
            cout << res[i];
        else
            cout << " " << res[i];
    }


    system("pause");
    return 0;
}

7-33 螺旋方阵

所谓“螺旋方阵”,是指对任意给定的N,将1到N×N的数字从左上角第1个格子开始,按顺时针螺旋方向顺序填入N×N的方阵里。本题要求构造这样的螺旋方阵。

输入格式:

输入在一行中给出一个正整数N(<10)。

输出格式:

输出N×N的螺旋方阵。每行N个数字,每个数字占3位。

输入样例:

5

输出样例:

  1  2  3  4  5
 16 17 18 19  6
 15 24 25 20  7
 14 23 22 21  8
 13 12 11 10  9

思路:两个方法:

  1. 可以设置四个变量分别代表螺旋矩阵的上、下、左、右边界,遍历到相应的下标使得对应的边界向方阵内部缩小即可
  2. 仔细看不难发现总共的数字量无非就是方阵边长的平方,所以还可以通过找规律的形式去编写程序

因为思路1比较简单利于实现,所以代码块我放思路2的实现代码

AC代码:

#include<bits/stdc++.h>
using namespace std;
int main()
{
	int f,i,n,j,a[10][10]={0},t,s;
	f=1;i=0;t=1;s=0;
	scanf("%d",&n);
	while(f<=n*n){
		for(j=s;j<n-s;j++){
			a[i][j]=f;
			f++;			
		}j=n-t;
		for(i=t;i<n-s;i++){
			a[i][j]=f;
			f++;
		}
		i=n-t;t++;
		for(j=n-t;j>=s;j--){
			a[i][j]=f;
			f++;
		}
		j=s;
		for(i=n-t;i>s;i--){
			a[i][j]=f;
			f++;
		}s++;
		i=s;
	}
	
	for(i=0;i<n;i++){
		for(j=0;j<n;j++){
			printf("%3d",a[i][j]);
		}printf("\n");
	}
	
	
	return 0;
 } 

7-34 吃火锅

 以上图片来自微信朋友圈:这种天气你有什么破事打电话给我基本没用。但是如果你说“吃火锅”,那就厉害了,我们的故事就开始了。

本题要求你实现一个程序,自动检查你朋友给你发来的信息里有没有 chi1 huo3 guo1

输入格式:

输入每行给出一句不超过 80 个字符的、以回车结尾的朋友信息,信息为非空字符串,仅包括字母、数字、空格、可见的半角标点符号。当读到某一行只有一个英文句点 . 时,输入结束,此行不算在朋友信息里。

输出格式:

首先在一行中输出朋友信息的总条数。然后对朋友的每一行信息,检查其中是否包含 chi1 huo3 guo1,并且统计这样厉害的信息有多少条。在第二行中首先输出第一次出现 chi1 huo3 guo1 的信息是第几条(从 1 开始计数),然后输出这类信息的总条数,其间以一个空格分隔。题目保证输出的所有数字不超过 100。

如果朋友从头到尾都没提 chi1 huo3 guo1 这个关键词,则在第二行输出一个表情 -_-#

输入样例1:

Hello!
are you there?
wantta chi1 huo3 guo1?
that's so li hai le
our story begins from chi1 huo3 guo1 le
.

输出样例1:

5
3 2

输入样例2:

Hello!
are you there?
wantta qi huo3 guo1 chi1huo3guo1?
that's so li hai le
our story begins from ci1 huo4 guo2 le
.

输出样例2:

5
-_-#

思路:优先利用string类型保存chi1 huo3 guo1,然后对每一行进行遍历判断是否存在即可 

AC代码:

#include<bits/stdc++.h>
using namespace std;
int main()
{
    int i, j, k, n, first = INT_MAX, count = 0;
    char * ch = new char[100];
    vector<string>nums;
    string item = "chi1 huo3 guo1";
    while (cin.getline(ch, 100, '\n')) {
        string s = ch;
        if (s[0] == '.' && s.length() == 1) break;
        nums.push_back(s);
    }
    for (i = 0; i < nums.size(); i++) {
        if (nums[i].find(item) != -1) {
            first = min(first, i + 1);
            count++;
        }
    }
    cout << nums.size() << endl;
    if (count == 0) 
        cout << "-_-#" << endl;
    else
        cout << first << " " << count << endl;

    system("pause");
    return 0;
}

7-35 复数四则运算

本题要求编写程序,计算2个复数的和、差、积、商。

输入格式:

输入在一行中按照a1 b1 a2 b2的格式给出2个复数C1=a1+b1i和C2=a2+b2i的实部和虚部。题目保证C2不为0。

输出格式:

分别在4行中按照(a1+b1i) 运算符 (a2+b2i) = 结果的格式顺序输出2个复数的和、差、积、商,数字精确到小数点后1位。如果结果的实部或者虚部为0,则不输出。如果结果为0,则输出0.0。

输入样例1:

2 3.08 -2.04 5.06

输出样例1:

(2.0+3.1i) + (-2.0+5.1i) = 8.1i
(2.0+3.1i) - (-2.0+5.1i) = 4.0-2.0i
(2.0+3.1i) * (-2.0+5.1i) = -19.7+3.8i
(2.0+3.1i) / (-2.0+5.1i) = 0.4-0.6i

输入样例2:

1 1 -1 -1.01

输出样例2:

(1.0+1.0i) + (-1.0-1.0i) = 0.0
(1.0+1.0i) - (-1.0-1.0i) = 2.0+2.0i
(1.0+1.0i) * (-1.0-1.0i) = -2.0i
(1.0+1.0i) / (-1.0-1.0i) = -1.0

思路:根据题意以及复数的和、差、积、商公式硬模拟即可,这里我用了一个round函数代表四舍五入 

AC代码:

#include<bits/stdc++.h>
using namespace std;
typedef long long int ll;
double a,b,c,d;
void print(double n,double m,char g)
{
    double x=round(b*10)/10;
    double y=round(d*10)/10;
    if(x>=0&&y>=0)
        printf("(%.1lf+%.1lfi) %c (%.1lf+%.1lfi) ",a,b,g,c,d);
    else if(x>=0&&y<0)
        printf("(%.1lf+%.1lfi) %c (%.1lf%.1lfi) ",a,b,g,c,d);
    else if(x<0&&y<0)
        printf("(%.1lf%.1lfi) %c (%.1lf%.1lfi) ",a,b,g,c,d);
    else if(x<0&&y>=0)
        printf("(%.1lf%.1lfi) %c (%.1lf+%.1lfi) ",a,b,g,c,d);//注意b,d的符号,并且是按四舍五入后的进行 
 
    if(n!=0&&m!=0&&m>0)
        printf("= %.1lf+%.1lfi\n",n,m);
    else if(n!=0&&m!=0&&m<0)
        printf("= %.1lf%.1lfi\n",n,m);
    else if(n==0&&m!=0)
        printf("= %.1lfi\n",m);
    else if(n!=0&&m==0)
        printf("= %.1lf\n",n);
    else if(n==0&&m==0)
        printf("= %.1lf\n",0);
}
int main()
{
    cin>>a>>b>>c>>d;
    double n,m;
    char g;
    n=round((a+c)*10)/10;
    m=round((b+d)*10)/10;
    g='+';
    print(n,m,g);
    n=round((a-c)*10)/10;
    m=round((b-d)*10)/10;
    g='-';
    print(n,m,g);
    n=round((a*c-b*d)*10)/10;
    m=round((a*d+b*c)*10)/10;
    g='*';
    print(n,m,g);
    n=(a*c+b*d)*1.0/(c*c+d*d);
    m=(b*c-a*d)*1.0/(c*c+d*d);
    n=round(n*10)/10;
    m=round(m*10)/10;
    g='/';
    print(n,m,g);
    
    return 0;
}

  • 0
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
通讯录的录入与显示pta解题思路可以分为以下几个步骤: 1. 首先,需要定义一个通讯录的数据结构,可以使用字典或者类来表示每条记录的信息,包括姓名、出生日期、性别、固定电话号码和移动电话号码。 2. 接下来,需要录入N条记录。可以使用循环来实现,每次循环输入一条记录的信息,并将其添加到通讯录。 3. 在录入完成后,需要根据要求显示任意某条记录。首先,需要读取输入的正整数K,表示要查询的记录编号。然后,根据编号从通讯录找到对应的记录,并将其信息显示出来。 下面是一个示例代码,演示了通讯录的录入与显示的解题思路: ```python # 定义通讯录的数据结构 address_book = [] # 录入N条记录 N = int(input("请输入记录的数量:")) for i in range(N): record = {} record['姓名'] = input("请输入姓名:") record['出生日期'] = input("请输入出生日期:") record['性别'] = input("请输入性别:") record['固定电话号码'] = input("请输入固定电话号码:") record['移动电话号码'] = input("请输入移动电话号码:") address_book.append(record) # 显示任意某条记录 K = int(input("请输入要查询的记录编号:")) record = address_book[K] print("姓名:", record['姓名']) print("出生日期:", record['出生日期']) print("性别:", record['性别']) print("固定电话号码:", record['固定电话号码']) print("移动电话号码:", record['移动电话号码']) ```

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值