程序开发实训 【专题二】 函数二


2020-05-03 作业笔记 程序开发实训

包含题目

1、旋转魔方阵
2、折叠方阵
3、方阵乘法运算
4、N 阶魔方阵
5、完美数
6、一元二次方程的根(不考虑虚根)
7、一元二次方程的根(考虑虚根)

注意

1.以下代码仅供参考,不代表最优解。
2.代码的运行结果与编译环境有关,以下代码均通本地测试,如果代码存在无法编译或输出异常,请检查运行环境。
3.如果发现问题或者您有更优的解,欢迎加群交流。

# 1、旋转魔方阵

【问题描述】

输入一个自然数N(N 属于 2 到 15),要求输出如下的魔方阵,即边长为 N*N,元素取值为 1 至 N*N,1 在左上角,呈顺时针方向依次放置各元素。

N=3 时:

1    2    3
8    9    4
7    6    5

【输入形式】

从标准输入读取一个整数 N。

【输出形式】

向标准输出打印结果。输出符合要求的方阵,每个数字占 5 个字符宽度,向右对齐,在每一行末均输出一个回车符。

#include <iostream>
#include <iomanip>
using namespace std;

const int Max = 15;

void display(int n, int **a)
{
    for (int i = 0; i < n; i++)
    {
        for (int j = 0; j < n; j++)
            cout << setw(5) << a[i][j];
        cout << endl;
    }
}

void cube(int n, int **a)
{
    int curr = 1;
    bool isOdd;
    n % 2 == 0 ? isOdd = false : isOdd = true;
    for (int i = 0; i < n / 2; i++)
    {
        int x = i, y = i;
        int steps = n - 1 - i * 2;
        while (steps-- > 0)
            a[x][y++] = curr++;
        steps = n - 1 - i * 2;
        while (steps-- > 0)
            a[x++][y] = curr++;
        steps = n - 1 - i * 2;
        while (steps-- > 0)
            a[x][y--] = curr++;
        steps = n - 1 - i * 2;
        while (steps-- > 0)
            a[x--][y] = curr++;
        if (isOdd)
            a[++x][++y] = curr;
    }
}

int main()
{
    int N;
    // 动态开辟二维数组
    int **a = new int *[Max];
    for (int i = 0; i < Max; i++)
        a[i] = new int[Max];
    cin >> N;
    cube(N, a);
    display(N, a);
    // 释放动态资源,避免内存泄漏
    for (int i = 0; i < Max; i++)
        delete[] a[Max];
    delete[] a;
    return 0;
}

# 2、折叠方阵

【问题描述】

给定一个起始数(大于等于 1,小于等于 20)和方阵的阶数(大于等于 1,小于等于 20),编程求得并输出该折叠方阵。一个起始数为 10,4 阶折叠方阵为:

10  11  14  19
13  12  15  20
18  17  16  21
25  24  23  22

【输入形式】

从标准输入中输入两个正整数分别表示起始数和方阵的阶数,以一个空格分隔这两个数字。

【输出形式】

将生成的折叠方阵按行输出到标准输出上,每个数字占 4 个字符的宽度,靠右对齐,各数字之间不再有空格分隔,每行末尾有回车换行。

#include <iostream>
#include <iomanip>
using namespace std;
// 安润鲁 2020年4月22日17:31:45
const int Max = 20;

void display(int n, int a[][Max])
{
    for (int i = 0; i < n; i++)
    {
        for (int j = 0; j < n; j++)
            cout << setw(4) << a[i][j];
        cout << endl;
    }
}

void foldcube(int start, int n, int a[][Max])
{
    int curr = start;
    for (int i = 0; i < n; i++)
    {
        int rowSteps = i + 1;
        int colSteps = i;
        int col = i, row = 0;
        while (rowSteps-- > 0)
            a[row++][col] = curr++;
        row--;
        while (colSteps-- > 0)
            a[row][--col] = curr++;
    }
}

int main()
{
    int start, n;
    int a[Max][Max] = {0};
    cin >> start >> n;
    foldcube(start, n, a);
    display(n, a);
    return 0;
}

# 3、方阵乘法运算

【问题描述】

从键盘输入一个正整数 n(n 属于[1,10]),表示进行乘法运算的两个整形方阵的阶。然后分别输入两个整形方阵 A 和 B,计算 A*B 后将结果输出到屏幕。

【输入形式】从键盘输入一个正整数,然后再输入两个整形方阵。

【输出形式】在屏幕上输出两个整形方阵的乘积。

#include <iostream>
#include <iomanip>
using namespace std;
// 2020年4月22日18:06:59
const int Max = 10;

void display(int n, int a[][Max])
{
    for (int i = 0; i < n; i++)
    {
        for (int j = 0; j < n; j++)
            cout << setw(10) << a[i][j];
        cout << endl;
    }
}

void setOneMatrix(int n, int matrix[][Max])
{
    for (int i = 0; i < n; i++)
        for (int j = 0; j < n; j++)
            cin >> matrix[i][j];
}

void multMatrix(int n, int a[][Max], int b[][Max], int res[][Max])
{
    for (int i = 0; i < n; i++)
        for (int j = 0; j < n; j++)
        {
            int sum = 0;
            for (int k = 0; k < n; k++)
                sum += a[i][k] * b[k][j];
            res[i][j] = sum;
        }
}

int main()
{
    int a[Max][Max], b[Max][Max];
    int res[Max][Max];
    int n;
    cin >> n;
    setOneMatrix(n, a);
    setOneMatrix(n, b);
    multMatrix(n, a, b, res);
    display(n, res);
    return 0;
}

# 4、N 阶魔方阵

【问题描述】

魔方阵指一个 A 是 N*N 矩阵(在本题中 N 仅为奇数,且 N>1),以自然数 1,2…… N2 个元素进行填充,每个位置上分别放置一个元素,使每行、每列以及主、副对角线上的元素之和都相等。

如 3*3 魔方阵,图在每行、每列、主对角线、副对角线上元素之和均为 15:

8  1  6
3  5  7
4  9  2

【输入形式】控制台输入一奇数 N。

【输出形式】输出一个 N*N 的魔方阵,其中每个数字占 4 位字符的宽度,向右对齐。

#include <iostream>
#include <iomanip>
using namespace std;
// 安润鲁 2020年4月23日16:22:28
const int N = 100;

void display(int n, int b[][N])
{
    for (int i = 1; i <= n; i++)
    {
        for (int j = 1; j <= n; j++)
            cout << setw(4) << b[i][j];
        cout << endl;
    }
}
void magic(int n, int A[][N])
{
    int row = 1, col = (n + 1) / 2;
    for (int k = 1; k <= n * n; k++)
    {
        A[row][col] = k;
        // 判断是否在第1行
        if (row == 1)
        {
            row = n;
            col + 1 > n ? col : col++;
            // 当到达右上边界,如果下一个坑位非零,将元素放在下方。
            A[row][col] != 0 ? row = 2 : row;
        }
        // 判断是否到达第n列
        else if (col == n)
        {
            col = 1;
            row--;
        }
        // 判断右上角元素是否为空
        else if (A[row - 1][col + 1] != 0 || (row == 1 && col == n))
            row++;
        else
        {
            row--;
            col++;
        }
    }
}

int main()
{
    int n;
    cin >> n;
    int b[N][N] = {0};
    magic(n, b);
    display(n, b);
    return 0;
}

# 5、完美数

【问题描述】

所有真约数(除本身之外的正约数)的和等于它本身的正整数叫做完美数,又叫做完全数或完备数。当所有真约数(除本身之外的正约数)的和小于它本身的正整数叫做亏数;相反情况时,叫做盈数。 比如“4”这个数,它的真约数有 1,2,其和是 3,3 比 4 本身小,这样的自然数就叫做亏数(又叫做缺数),类似的还有 5,7,8 等等。比如“12”这个数,它真约数有 1,2,3,4,6,其和是 16,16 比 12 本身大,这样的自然数就叫做盈数(又叫做丰数,或过剩数或富裕数),类似的还有 12,18,20 等等。 完美数就是既不盈余,又不亏欠的自然数,比如“6”这个数,它真约数有 1,2,3,其和是 1+2+3=6,刚好等于 6 本身。 要求用户从键盘上输入任意一个自然数,判断该数是盈数、亏数还是完美数。如果该数是亏数,输出“Deficit”;如果该数是盈数,输出“Surplus”;如果该数是完美数,则输出“Perfect” 。

【输入形式】一个自然数。

【输出形式】

如果该数是亏数,输出“Deficit”;如果该数是盈数,输出“Surplus”;如果该数是完美数,输出“Perfect”。

#include <iostream>
#include <string>
using namespace std;

string perfectNum(int n)
{
    int s = 0;
    for (int i = 1; i < n; i++)
    {
        if (n % i == 0)
            s += i;
    }
    if (s > n)
        return "Surplus";
    else if (s < n)
        return "Deficit";
    else
        return "Perfect";
}

int main()
{
    int n;
    cin >> n;
    cout << perfectNum(n) << endl;
    return 0;
}

# 6、一元二次方程的根(不考虑虚根)

【问题描述】

在实数范围内求方程 ax^2+bx+c=0 的根。方程的系数 a、b、c 由用户从键盘上输入。

【输入形式】

方程的系数 a、b、c(假设是整型数据)。

【输出形式】

实数范围内求方程的根,如果存在实数根,结果保留两位小数且 x1>=x2。 当有两个实根时,要求先输出实根 x=[-b+√(b^2-4ac)]/2a,空格后再输出实根 x=[-b-√(b2-4ac)]/2a; 当有两个相同的实根时,仅输出一个实根 x=[-b+√(b2-4ac)]/2ax=[-b-√(b2-4ac)]/2a 即可;当没有实根时,输出"NONE"。

#include <iostream>
#include <cmath>
#include <iomanip>
using namespace std;

void getRoot(int a, int b, int c)
{
    int delta = b * b - 4 * a * c;
    if (delta < 0)
        cout << "NONE" << endl;
    else if (delta > 0)
    {
        float r1, r2;
        r1 = (-b + sqrt(delta)) / (2.0 * a);
        r2 = (-b - sqrt(delta)) / (2.0 * a);
        cout << fixed << setprecision(2) << r1 << " " << r2 << endl;
    }
    else
        cout << fixed << setprecision(2) << -b / (2.0 * a) << endl;
}

int main()
{
    int a, b, c;
    cin >> a >> b >> c;
    getRoot(a, b, c);
    return 0;
}

# 7、一元二次方程的根(考虑虚根)

【问题描述】 在实数范围内求方程 ax^2+bx+c=0 的根。方程的系数 a、b、c 由用户从键盘上输入。

【输入形式】方程的系数 a、b、c(假设是整型数据)。

【输出形式】

实数范围内求方程的根,如果存在实数根,结果保留两位小数且 x1>=x2。当有两个实根时,要求先输出实根x=[-b+√(b2-4ac)]/2a,空格后再输出实根x=[-b-√(b2-4ac)]/2a;当有两个相同的实根时,仅输出一个实根x=[-b+√(b2-4ac)]/2ax=[-b-√(b2-4ac)]/2a即可;当没有实根时,输出一对共轭复根。

#include <iostream>
#include <cmath>
#include <iomanip>
using namespace std;

void getRoot(int a, int b, int c)
{
    int delta = b * b - 4 * a * c;
    if (delta < 0)
    {
        float real, img;
        real = -b / 2.0 * a;
        img = sqrt(-delta) / 2.0 * a;
        cout << fixed << setprecision(2) << real << '+' << img << 'i' << " ";
        cout << fixed << setprecision(2) << real << '-' << img << 'i' << endl;
    }
    else if (delta > 0)
    {
        float r1, r2;
        r1 = (-b + sqrt(delta)) / 2.0 * a;
        r2 = (-b - sqrt(delta)) / 2.0 * a;
        cout << fixed << setprecision(2) << r1 << " " << r2 << endl;
    }
    else
        cout << fixed << setprecision(2) << -b / (2.0 * a) << endl;
}

int main()
{
    int a, b, c;
    cin >> a >> b >> c;
    getRoot(a, b, c);
    return 0;
}

# 评论交流

最后,如果你觉得笔记对你有帮助,不妨赞赏一杯可乐😅

QQ 交流群 217394861

Last Updated: 5/30/2020, 10:01:03 AM