C++算法设计与分析例题代码(基础篇)

C++算法设计与分析例题代码


Wild Chicken Programing TANXL


前言

最近在读清华大学出版社的算法设计与分析(第三版),把书中的例题完成了一下,并记录于此。(已完成)


一、求1/1!-1/3!+1/5!-1/7!+…+(-1)^(n+1)/(2n-1)!

#include <iostream>
using namespace std;
int main()
{
    int n, sign = 1;//n为用户输入值,代表数字个数  sign用于数字的正负
    float s = 1, t = 1;//s为总值  t用于计算单个数字的大小
    cout << "计算1/1!-1/3!+1/5!-1/7!+...+(-1)^n+1/(2n-1)!" << endl;
    cout << "输入n的值开始计算" << endl;
    cin >> n;
    cout << "1/1!";
    for (int i = 2; i <= n; i++)
    {
        sign = -sign;
        t = t * (2 * i - 2) * (2 * i - 1);
        if (sign > 0)cout << "+";
        else cout << "-";
        cout << "1/" << 2 * i - 1 << "!";
        s = s + sign / t;
    }
    cout << endl << "总值为 :" << s << endl;
}

二、一个数如果恰好等于它的因子之和(包括1,但不包含这个数本身),这个数就称为完数。

例如,28的因子为1,2,4,7,14,而28=1+2+4+7+14。因此28是“完数”。编写算法找出1000之内的所有完数,并按下面格式输出其因子:28 it’s factors are 1,2,4,7,14。

#include <iostream>
using namespace std;
int main()
{
    int i, k, j, s, a[30];
    for (i = 1; i <= 1000; i++)
    {
        s = 1;//因子总和,每次开始时s重置为1,因为1总是包含在因子里所以不为0。
        k = 0;//数组中储存因子的索引
        for (j = 2; j < i; j++)//可以确保不存放重复因子
        {
            if (i % j == 0)//判断是否整除
            {
                s += j;
                a[k] = j;//数组中存放因子
                k++;//索引+1
            }
            if (i == s && j == i - 1)//j==i-1确保完整遍历,否则中途满足条件也会输出  例如24 : 1 2 3 4 6 8 12
            {//                        到8时如果没有加入j==i-1的限制条件就会立刻输出 24 it's factors are : 1 2 3 4 6 8
                cout << s << " it's factors are : 1";//同时j==i-1保证了,满足条件时仅输出一次!
                for (j = 0; j < k; j++)
                {
                    cout << "," << a[j];
                }
                cout << endl;
            }
        }
    }
}

三、求一个矩阵的鞍点,即在行上最小而在列上最大的点。

#include <iostream>
using namespace std;
void readmtr(int a[20][20],int n)//用于输入完整矩阵
{
    int i, j;
    cout << "输入NxN的矩阵:" << endl;
    for (i = 0; i < n; i++)
    {
        for (j = 0; j < n; j++)
        {
            cout << endl << "第" << i + 1 << "行,第" << j + 1 << " : ";
            cin >> a[i][j];
        }
        cout << endl;
    }
}
void printmtr(int a[20][20], int n)//输入矩阵后立即调用,检查是否有错误
{
    int i, j;
    for (i = 0; i < n; i++)
    {
        for (j = 0; j < n; j++)
        {
            cout << "  " << a[i][j];
        }
        cout << endl;
    }
}
int main()
{
    int a[20][20], i, j, k, minj, t, n = 10, kz = 0;
    cout << "请输入正方形矩阵的边长:";//边长上限为20
    cin >> n;
    readmtr(a, n);
    printmtr(a, n);
    for (i = 0; i < n; i++)
    {
        t = a[i][0];
        minj = 0;
        for (j = 1; j < n; j++)//开始检查鞍点
        {
            if (a[i][j] < t)
            {
                t = a[i][j];
                minj = j;
            }
        }
        for (k = 0; k < n; k++)
        {
            if (a[k][minj] > t)
                break;
        }
        if (k < n)
            continue;
        cout << "鞍点是(" << i + 1 << " , " << minj + 1 << ")" << endl;
        cout << "鞍点的值为 : " << a[i][minj] << endl;
        kz = 1;
        if (i != n - 1 && j != n - 1)//确保完整遍历可以找出所有的鞍点,另外可以去掉if改成break;表示只求一个鞍点
            continue;
        else
            break;
    }
    if (kz == 0)//如果有鞍点则kz值为1
        cout << endl << "没有鞍点!" << endl;
}

四、编写算法:

打印具有下面规律的图形
_1
_5__2
_8__6__3
10__9__7__4

#include <iostream>
using namespace std;
int main()
{
    int i, j, a[20][20], n, k;
    cin >> n;
    k = 1;
    for (i = 1; i <= n; i++)
    {
        for (j = 1; j <= n + 1 - i; j++)
        {
            a[i - 1 + j][j] = k;//第i层第j列对应的数组元素
            k++;//递增的赋值
        }
    }
    for (i = 1; i <= n; i++)
    {
        cout << endl;
        for (j = 1; j <= i; j++)
        {
            cout << " " << a[i][j];
        }
    }
}

五、汉诺塔问题:

古代有一个梵塔,塔内有3个基座A,B,C开始时A基座上有64个盘子,但每次只允许移动一个盘子,且在移动过程中,3个基座上的盘子都始终保持大盘在下,小盘在上。移动过程中可以利用C基座做辅助。请编程打印出移动过程。

#include <iostream>
using namespace std;
void hanoi(int n, char a, char b, char c)
{
	if (n > 0)
	{
		hanoi(n - 1, a, c, b);//n-1个盘子从A基座借助C基座移动到B基座
		cout << "Move dish ," << n << ".from pile " << a << " to " << b << endl;//把A基座剩下的一个盘子移动到B
		hanoi(n - 1, c, b, a);//把C基座的n-1个盘子借助A基座移动到B基座
	}
}
int main()
{
	int n;
	cout << "请输入A基座上的盘子数";
	cin >> n;
	hanoi(n, 'A', 'B', 'C');
}

六、整数的分划问题。

对于一个正整数n的分划,就是把n表示成一系列正整数之和的表达式。注意,分划与顺序无关,例如6=5+1和6=1+5被认为是同一种分划。另外,这个整数n本身也算是一种分划。
例如,对于正整数n=6,它可以分划为:
6
5+1
4+2 4+1+1
3+3 3+2+1 3+1+1+1
2+2+2 2+2+1+1 2+1+1+1+1 1+1+1+1+1+1

#include <iostream>
using namespace std;
int Divinteger(int n, int m)
{
	if (n == 1 || m == 1)//最底部的值
		return 1;
	else if (n < m)//n<m时,即使m再大也没意义
		return Divinteger(n, n);
	else if (n == m)//n=m时,往下分永远只有一个n本身的数字
		return 1 + Divinteger(n, n - 1);
	else//正常情况
		return Divinteger(n, m - 1) + Divinteger(n - m, m);
}
int main()
{
	int n;
	cout << "请输入要分划的整数:";
	cin >> n;
	while(n < 1)
	{
		cout << "输入参数错误!请重新输入" << endl;
		cin >> n;
	}
	cout <<"参数 "<<n<<" 有 "<< Divinteger(n, n)<<" 种分法.";
}

七、任给十进制的正整数,请从低位到高位逐位输出各位数字。

#include <iostream>
using namespace std;
void f(int n)
{
	if (n < 10)
		cout << n << endl;
	else
	{
		cout << n % 10 << endl;
		f(n / 10);
	}
}
int main()
{
	int n;
	cout << "(循环算法)请输入n的值:";
	cin >> n;
	while (n >= 10)
	{
		cout << n % 10 << endl;
		n /= 10;
	}
	cout << n << endl;
	cout << "(递归算法)请输入n的值:";
	cin >> n;
	f(n);
}

八、任给十进制的正整数,请从高位到低位逐位输出各位数字。

#include <iostream>
using namespace std;
void f(int n)
{
	if (n < 10)
		cout << n << endl;
	else
	{
		f(n / 10);
		cout << n % 10 << endl;
	}
}
int main()
{
	int n, j, i = 0, a[16];
	cout << "(循环算法)请输入n的值:";
	cin >> n;
	while (n >= 10)
	{
		a[i] = n % 10;
		i++;
		n /= 10;
	}
	a[i] = n;
	for (j = i; j >= 0; j--)
		cout << a[j] << endl;
	cout << "(递归算法)请输入n的值:";
	cin >> n;
	f(n);
}

九、任何一个正整数都可以用2的幂次方表示。

例如:137=27+23+20,同时约定几次方用括号表示,即ab可表示为a(b),由此可知,137可表示为:2(7)+2(3)+2(0),进一步:7+22+2+20(21用2表示)3=2+20。所以最后137可表示为:
2(2(2)+2+2(0)+2(2+2(0))+2(0)。
又如:1315=210+28+25+2+1,所以1315最后可表示为:
2(2(2+2(0))+2)+2(2(2+2(0)))+2(2(2)+2(0))+2+2(0)。
输入:正整数(n<=20 000)。
输出:符合约定的n的0,2表示(在表示中不能有空格)。
算法设计1:

#include <iostream>
using namespace std;
void try_(int n, int r)
{
    if (n == 1)
        cout << "2^" << r;
    else
    {
        try_(n / 2, r + 1);
        if (n % 2 == 1)
            cout << "+2^" << r;
    }
}
int main()
{
    int n;
    cout << "请输入一个小于等于20 000的值" << endl;
    cin >> n;
    if (n >= 1)
        try_(n, 0);
    else
        cout << "data error";
}

算法设计2:

#include <iostream>
using namespace std;
void try_(int n, int r)
{
    if (n == 1)
    {
        switch (r)
        {
        case 0:cout << "2(0)"; break;
        case 1:cout << "2"; break;
        case 2:cout << "2(2)"; break;
        default:cout << "2("; try_(r, 0); cout << ")";
        }
    }
    else
    {
        try_(n / 2, r + 1);
        if (n % 2 == 1)
        {
            switch (r)
            {
            case 0:cout << "+2(0)"; break;
            case 1:cout << "+2"; break;
            case 2:cout << "+2("; try_(r, 0); cout << ")";
            default:cout << "+2("; try_(r, 0); cout << ")";
            }
        }
    }
}
int main()
{
    int n;
    cin >> n;
    if (n >= 1)
        try_(n, 0);
    else
        cout << "data error";
}

十、找出n个自然数(1,2,3,…,n)中取r个数的组合。

例如,当n=5,r=3时,所有组合为:
1 2 3
1 2 4
1 2 5
1 3 4
1 3 5
1 4 5
2 3 4
2 3 5
2 4 5
3 4 5
total=10 {组合的总数}

循环算法设计:

#include <iostream>
using namespace std;
int main()
{
    int n = 5, i, j, k, t = 0;
    for (i = 1; i <= n; i++)
    {
        for (j = 1; j <= n; j++)
        {
            for (k = 1; k <= n; k++)
            {
                if (i < j && j < k)
                {
                    t++;
                    cout << i << "  " << j << "  " << k << endl;
                }
            }
        }
    }
    cout << "total=" << t << endl;
}

数据结构设计:

#include <iostream>
using namespace std;
int a[100];
void comb(int m, int k)
{
    int i, j;
    for (i = m; i >= k; i--)
    {
        a[k] = i;
        if (k > 1)
            comb(i - 1, k - 1);
        else
        {
            for (j = a[0]; j > 0; j--)
                cout << a[j];
            cout << endl;
        }
    }
}
int main()
{
    int n, r;
    cout << "请输入n的值:";
    cin >> n;
    cout << "请输入r的值:";
    cin >> r;
    if (r > n)
        cout << "Input n,r error";
    else
    {
        a[0] = r;
        comb(n, r);
    }
}

十一、某校决定由全校学生选举自己的学生会主席。

有5个候选人,编号分别为1,2,3,4,5,选举其中一人为学生会主席,每个学生一张选票,只能填写一人。请编程完成统计选票的工作。

#include <iostream>
using namespace std;
int main()
{
    int i, xp, a[6] = { 0,0,0,0,0,0 };
    cout << "输入数据直到输入值为-1" << endl;
    cin >> xp;
    while (xp != -1)
    {
        if (xp >= 1 && xp <= 5)
            a[xp] = a[xp] + 1;
        else
            cout << xp << "输入错误" << endl;
        cin >> xp;
    }
    for (i = 1; i <= 5; i++)
        cout << i << "号获得了" << a[i] << "票" << endl;
}

十二、编程统计身高(单位为厘米)。

统计150 ~ 154、155 ~ 159、160 ~ 164、165 ~ 169、170 ~ 174、175 ~ 179、低于150和高于179,共8档进行。

#include <iostream>
using namespace std;
int main()
{
    int i, sg, a[8] = { 0,0,0,0,0,0,0,0 };
    cout << "input height data until input -1" << endl;
    cin >> sg;
    while (sg != -1)
    {
        if (sg > 179)
            a[7] = a[7] + 1;
        else
        {
            if (sg < 150)
                a[0] = a[0] + 1;
            else
                a[sg / 5 - 29] = a[sg / 5 - 29] + 1;
        }
        cin >> sg;
    }
    for (i = 0; i <= 7; i++)
        cout << i + 1 << "  field the number of people:" << a[i] << endl;
}

十三、一次考试共考了语文、代数和外语3科。

某小组共有9人,考后各科及格名单如表3-2所示,请编写算法找出3科全及格的学生的名单(学号)。
科目————及格学生学号
语文————1,9,6,8,4,3,7
代数————5,2,9,1,3,7
外语————8,1,6,7,3,5,4,9

算法设计1:

#include <iostream>
using namespace std;
int main()
{
	int a[7], b[6], c[8], i, j, k, v;
	for (i = 0; i <= 6; i++)
	{
		cout << "第" << i + 1 << "个语文及格学号 :";
		cin >> a[i];
	}
	for (i = 0; i <= 5; i++)
	{
		cout << "第" << i + 1 << "个代数及格学号 :";
		cin >> b[i];
	}
	for (i = 0; i <= 7; i++)
	{
		cout << "第" << i + 1 << "个外语及格学号 :";
		cin >> c[i];
	}
	for (i = 0; i <= 6; i++)
	{
		v = a[i];
		for (j = 0; j <= 5; j++)
		{
			if (b[j] == v)
			{
				for (k = 0; k <= 7; k++)
				{
					if (c[k] == v)
					{
						cout << endl << "学号为" << v << "的学生都及格了" << endl;
						break;
					}
				}
			}
		}
	}
}

算法设计2:

#include <iostream>
using namespace std;
int main()
{
	int a[10] = { 0,0,0,0,0,0,0,0,0,0 }, i, xh;
	cout << "输入及格学生学号(不分科目)" << endl;
	for (i = 1; i <= 21; i++)
	{
		cout << i + 1 << " . ";
		cin >> xh;
		a[xh] = a[xh] + 1;
	}
	for (xh = 1; xh <= 9; xh++)
	{
		if (a[xh] == 3)
		{
			cout << endl << "学号为" << xh << "的学生都及格了" << endl;
		}
	}
}

十四、编写算法将数字序号“翻译”成英文符号。

例如:将编号35706“翻译”成英文编号 three-five-seven-zero-six。
算法设计1:

#include <iostream>
using namespace std;
int main()
{
    int i, a[10], ind;
    long num1, num2;
    char eng[10][6] = { "zero","one","two","three","four","five","six","seven","eight","nine" };
    cout << "输入一个数字 :";
    cin >> num1;
    num2 = num1;
    ind = 0;
    while (num2 != 0)
    {
        a[ind] = num2 % 10;
        ind++;
        num2 /= 10;
    }
    cout << num1 << ",English_exp: " << eng[a[ind - 1]];
    for (i = ind - 2; i >= 0; i--)
        cout << "-" << eng[a[i]];
}

算法设计2:

#include <iostream>
using namespace std;
int main()
{
    int i = 0, n;
    char num[10];
    char eng[10][6] = { "zero","one","two","three","four","five","six","seven","eight","nine" };
    cout << "输入一个数字 :";
    cin >> num;
    n = strlen(num);
    if (n == 0)
        cout << "输入错误!" << endl;
    else
    {
        cout << num << " , English_exp : " << eng[num[0] - 48];
        for (i = 1; i <= n - 1; i++)
        {
            cout << "-" << eng[num[i] - 48];
        }
    }
}

十五、一个顾客买了价值x元的商品(不考虑角、分),并将y元的钱交给售货员。

编写算法:在各种币值的钱都很充分的情况下,使售货员能用张数最少的钱币找给顾客。

#include <iostream>
using namespace std;
int main()
{
    int i, x, y, z, a, b[7] = { 0,50,20,10,5,2,1 }, s[7];
    cout << "请输入X的值:";
    cin >> x;
    cout << "请输入Y的值:";
    cin >> y;
    z = y - x;
    cout << y << "-" << x << "=" << z << endl;
    for (i = 1; i <= 6; i++)
    {
        a = z / b[i];
        s[i] = a;
        z -= a * b[i];
    }
    for (i = 1; i <= 6; i++)
    {
        if (s[i] != 0)
            cout << b[i] << " 元----" << s[i] << "张" << endl;
    }
}

十六、求x使x2为一个各位数字互不相同的9位数。

#include <iostream>
using namespace std;
int main()
{
    long x, y1, y2;
    int p[10], i, t, k, num = 0;
    for (x = 10000; x < 32000; x++)
    {
        for (i = 0; i <= 9; i++)
            p[i] = 1;
        y1 = x * x;
        y2 = y1;
        k = 0;
        for (i = 1; i <= 9; i++)
        {
            t = y2 % 10;
            y2 = y2 / 10;
            if (p[t] == 1)
            {
                k++;
                p[t] = 0;
            }
            else
                break;
        }
        if (k == 9)
        {
            num++;
            cout << "No." << num << " : n = " << x << "  n^2 = " << y1 << endl;
        }
    }
}

十七、游戏问题:

12个小朋友手拉手站成一个圆圈,从某一个小朋友开始报数,报到7的那个小朋友退到圈外,然后他的下一位重新报“1”。这样继续下去,直到最后只剩下一个小朋友。求解这个小朋友原来站在什么位置上。

#include <iostream>
using namespace std;
int main()
{
    int a[100], i, k, p, m, n, x;
    cout << "input numbers of game :";
    cin >> n;
    cout << "input serial number of game start :";
    cin >> k;
    cout << "input number of out ring :";
    cin >> m;
    for (i = 1; i <= n; i++)
        a[i] = 1;
    p = 0;
    k--;
    cout << "wash out :";
    while (p < n - 1)
    {
        x = 0;
        while (x < m)
        {
            k++;
            if (k > n)
            {
                k = 1;
                x += a[k];
            }
        }
        cout << k;
        a[k] = 0;
        p++;
    }
    for (i = 1; i <= n; i++)
    {
        if (a[i] == 1)
            cout << "i = " << i;
    }
}

十八、高精度数据×长整数。

#include <iostream>
using namespace std;
int main()
{
	long b, c, d;
	int a[256], i, j, n;
	char s1[256];
	cout << "Input a great number :" << endl;
	cin >> s1;
	cout << "Input a long integer number :" << endl;
	cin >> c;
	n = strlen(s1);
	d = 0;
	for (i = 0, j = n - 1; i < n; i++, j--)
	{
		b = (s1[j] - 48) * c + d;
		a[i] = b % 10;
		d = b / 10;
	}
	while (d != 0)
	{
		a[n] = d % 10;
		d /= 10;
		n++;
	}
	cout << endl << "相乘的值为:";
	for (i = n - 1; i >= 0; i--)
		cout << a[i];
}

十九、编程求当n<=100时,n!的准确值。

#include <iostream>
using namespace std;
int main()
{
	long a[256], b, d;
	int m, n, i, j, r;
	cout << "请输入N的值 : ";
	cin >> n;
	m = log(n) * n / 6 + 2;
	a[1] = 1;
	for (i = 2; i <= m; i++)
		a[i] = 0;
	d = 0;
	for (i = 2; i <= n; i++)
	{
		for (j = 1; j <= m; j++)
		{
			b = a[j] * i + d;
			a[j] = b % 1000000;
			d = b / 1000000;
		}
		if (d != 0)
			a[j] = d;
	}
	for (i = m; i >= 1; i--)
	{
		if (a[i] == 0)
			continue;
		else
		{
			r = i;
			break;
		}
	}
	cout << n << "! = " << a[r];
	for (i = r - 1; i >= 1; i--)
	{
		if (a[i] > 99999)
		{
			cout << a[i] << " ";
			continue;
		}
		else if (a[i] > 9999)
		{
			cout << "0" << a[i] << " ";
			continue;
		}
		else if (a[i] > 999)
		{
			cout << "00" << a[i] << " ";
			continue;
		}
		else if (a[i] > 99)
		{
			cout << "000" << a[i] << " ";
			continue;
		}
		else if (a[i] > 9)
		{
			cout << "0000" << a[i] << " ";
			continue;
		}
		cout << "00000" << a[i] << " ";
	}
}

二十、编程打印有如下规律的n×n方阵。

使左对角线和右对角线上的元素为0,它们上方的元素为1,左边的元素为2,下方元素为3,右边元素为4,下图是一个符合条件的五阶矩阵。
0__1__1__1__0
2__0__1__0__4
2__2__0__4__4
2__0__3__0__4
0__3__3__3__0

#include <iostream>
using namespace std;
int main()
{
    int i, j, n, rec[50][50];
    cout << "请输入矩形的边长 : ";
    cin >> n;
    for (i = 0; i < n; i++)
    {
        for (j = 0; j < n; j++)
        {
            if (i <= j && i + j <= n - 1)
                rec[i][j] = 1;
            if (i <= j && i + j >= n - 1)
                rec[i][j] = 4;
            if (i >= j && i + j <= n - 1)
                rec[i][j] = 2;
            if (i >= j && i + j >= n - 1)
                rec[i][j] = 3;
            if (i == j)
                rec[i][j] = 0;
            if (i + j == n - 1)
                rec[i][j] = 0;
        }
    }
    for (i = 0; i < n; i++)
    {
        for (j = 0; j < n; j++)
        {
            cout << rec[i][j] << " ";
        }
        cout << endl;
    }
}

二十一、螺旋阵:任意给定n值,按如下螺旋的方式输出方阵。

n=3 输出:
1__8__7
2__9__6
3__4__5
n=4 输出:
1__12__11__10
2__13__16__ 9
3__14__15__ 8
4__ 5 __ 6 __ 7
算法设计1:

#include <iostream>
using namespace std;
int main()
{
	int i, j, a[100][100], n, k = 1;
	cout << "请输入矩形的边长 : ";
	cin >> n;
	for (i = 1; i <= n / 2; i++)
	{//j不代表列,j为一个临时变量
		for (j = i; j <= n - i; j++)//左侧
		{
			a[j][i] = k;
			k++;
		}
		for (j = i; j <= n - i; j++)//下方
		{
			a[n + 1 - i][j] = k;
			k++;
		}
		for (j = n + 1 - i; j > i; j--)//右侧
		{
			a[j][n + 1 - i] = k;
			k++;
		}
		for (j = n + 1 - i; j > i; j--)//上方
		{
			a[i][j] = k;
			k++;
		}
	}
	if (n % 2 == 1)//边长为单数时,中心点的赋值
	{
		i = (n + 1) / 2;
		a[i][i] = n * n;
	}
	for (i = 1; i <= n; i++)
	{
		for (j = 1; j <= n; j++)
		{
			cout << a[i][j] << "\t";
		}
		cout << endl << endl << endl << endl;
	}
}

算法设计2:

#include <iostream>
using namespace std;
int main()
{
	int i, j, k, n, a[100][100], b[2], x, y;
	cout << "请输入矩形的边长 : ";
	cin >> n;
	b[0] = 0;
	b[1] = 1;
	k = n;
	int t = 1;
	x = 1;
	while (x <= n * n)
	{
		for (y = 1; y <= 2 * k - 1; y++)
		{
			b[y / (k + 1)] = b[y / (k + 1)] + t;
			a[b[0]][b[1]] = x;
			x++;
		}
		k--;
		t = -t;
	}
	for (i = 1; i <= n; i++)
	{
		for (j = 1; j <= n; j++)
			cout << a[i][j] << "\t";
		cout << endl << endl << endl;
	}
}

二十二、魔方阵是我国古代发明的一种数字游戏:

n阶魔方是指这样一种方阵,它的每一行、每一列以及对角线上的各数之和为一个相同的常数,这个常数是:n×(n2+1)/2,此常数被称为魔方阵常数。由于偶次阶魔方阵(n=偶数)求解起来比较困难,这里只考虑n为奇数的情况。
以下就是一个n=3的魔方阵:
6__1__8
7__5__3
2__9__4
它的各行、各列及对角线上的元素之和为15。

#include <iostream>
using namespace std;
int main()
{
	int i, j, i1, j1, x, n, a[100][100];
	cout << "input an odd number : ";
	cin >> n;
	while (n % 2 == 0)
	{
		cout << "input error !" << endl;
		cout << "input an odd number : ";
		cin >> n;
	}
	for (i = 1; i <= n; i++)
		for (j = 1; j <= n; j++)
			a[i][j] = 0;
	i = 1;
	j = int((n + 1) / 2);
	x = 1;
	while (x <= n * n)
	{
		a[i][j] = x;
		x++;
		i1 = i;
		j1 = j;
		i--;
		j--;
		if (i == 0)
			i = n;
		if (j == 0)
			j = n;
		if (a[i][j] != 0)
		{
			i = i1 + 1;
			j = j1;
		}
	}
	for (i = 1; i <= n; i++)
	{
		for (j = 1; j <= n; j++)
			cout << a[i][j] << "\t";
		cout << endl << endl << endl;
	}
}

二十三、统计问题:找链环数字对的出现频率。

输入n(2≤n≤100)个数字(即0与9之间的数据),然后统计出这组数中相邻两数字组成的链环数字对出现的次数。如:当既有(0,3)又有(3,0)出现时,称他们为链环数字对,算法要统计输出它们各自的出现次数。

#include <iostream>
using namespace std;
int main()
{
    int a[10][10], n, i, j, k1, k0;
    for (i = 0; i <= 9; i++)
        for (j = 0; j <= 9; j++)
            a[i][j] = 0;
    cout << "How many is numbers :";
    cin >> n;
    cout << "Please input these numbers " << endl;
    cout << "1. :";
    cin >> k0;
    for (i = 2; i <= n; i++)
    {
        cout << endl << i << ". :";
        cin >> k1;
        a[k0][k1] = a[k0][k1] + 1;
        k0 = k1;
    }
    for (i = 0; i <= 9; i++)
        for (j = 0; j <= 9; j++)
            if (a[i][j] != 0 && a[j][i] != 0)
            {
                cout << "( " << i << " , " << j << " )=" << a[i][j];
                cout << "( " << j << " , " << i << " )=" << a[j][i] << endl;
                a[i][j] = 0;//防止反向重复输出,取出之后原值赋为0
                a[j][i] = 0;
            }
}

二十四、有3n个花盆,红色、蓝色和黄色的各n个。

开始时排列的顺序是混乱的,如黄、红、蓝、黄、黄、蓝、黄、红、红、黄、蓝、红、黄、红、黄、蓝、蓝、红、红、红、黄、蓝、蓝、黄、黄、黄、红、红、蓝、蓝、蓝。
请编写一程序:将各花盆按红、黄、蓝、红、黄、蓝…的顺序排列,而且要求花盆之间的交换次数最少。

#include <iostream>
using namespace std;
int main()
{
	int n, a[100][4], i, j, k, t, m = 0;
	cout << "请输入花盆的总数(3的倍数) :";
	cin >> n;
	n = n / 3;
	cout << "1表示红花盆 2表示黄花盆 3表示蓝花盆" << endl;
	for (i = 1; i <= n; i++)
	{
		for (j = 1; j <= 3; j++)
		{
			cout << i << " " << j << " .";
			cin >> a[i][j];
		}
	}
	for (i = 1; i <= n; i++)
	{
		if (a[i][1] == 2)
		{
			for (j = 1; j <= n; j++)
			{
				if (a[j][2] == 1)
				{
					t = a[i][1];
					a[i][1] = a[j][2];
					a[j][2] = t;
					m += 3;
					break;
				}
			}
		}
		if (a[i][1] == 3)
		{
			for (j = 1; j <= n; j++)
			{
				if (a[j][3] == 1)
				{
					t = a[i][1];
					a[i][1] = a[j][3];
					a[j][3] = t;
					m += 3;
					break;
				}
			}
		}
		if (a[i][2] == 3)
		{
			for (j = 1; j <= n; j++)
			{
				if (a[j][3] == 2)
				{
					t = a[i][2];
					a[i][2] = a[j][3];
					a[j][3] = t;
					m += 3;
					break;
				}
			}
		}
	}
	for (i = 1; i <= n; i++)
	{
		if (a[i][1] == 2)
		{
			for (j = 1; j <= n; j++)
			{
				if (a[j][2] == 3)
				{
					for (k = 1; k <= n; k++)
					{
						if (a[j][3] == 1)
						{
							t = a[i][1];
							a[i][1] = a[j][2];
							a[j][2] = a[k][3];
							a[k][3] = t;
							m += 4;
							break;
						}
					}
				}
			}
		}
		if (a[i][1] == 3)
		{
			for (j = 1; j <= n; j++)
			{
				if (a[j][2] == 1)
				{
					for (k = 1; k <= n; k++)
					{
						if (a[j][3] == 2)
						{
							t = a[i][1];
							a[i][1] = a[j][2];
							a[j][2] = a[k][3];
							a[k][3] = t;
							m += 4;
							break;
						}
					}
				}
			}
		}
	}
	cout << "move = " << m << endl;
	for (i = 1; i <= n; i++)
	{
		for (j = 1; j <= 3; j++)
		{
			cout << a[i][j] << "\t";
		}
		cout << endl;
	}
}

二十五、一次考试,共考了五门课。

统计50个学生中至少有3门课成绩高于90分的人数。

#include <iostream>
using namespace std;
int main()
{
    int a[5], i, j, s, num = 0;
    cout << "请输入成绩" << endl;
    for (i = 1; i <= 50; i++)
    {
        s = 0;
        for (j = 0; j <= 4; j++)
        {
            cout << "学生 " << i << " . 科目" << j + 1 << "  ";
            cin >> a[j];
            if (a[j] >= 90)
                s++;
        }
        if (s >= 3)
            num++;
    }
    cout << "The number is " << num << endl;
}

二十六、开灯问题:

有从1到n依次编号的n个同学和n盏灯。1号同学将所有的灯都关掉;二号同学将编号为2的倍数的灯都打开;3号同学则将编号为3的倍数的灯做相反处理(该号如果灯打开的,则关掉;如关闭的,则打开);以后的同学都将自己编号的倍数的灯,做相反处理。问经n个同学操作后,哪些灯是打开的?

#include <iostream>
using namespace std;
int main()
{
    int i, j, n, a[100];
    cout << "请输入N的值";
    cin >> n;
    for (i = 0; i < n; i++)
        a[i] = 0;
    for (j = 1; j < n; j++)
    {
        for (i = 1; i < n; i++)
        {
            if ((i + 1) % (j + 1) == 0)
            {
                if (a[i] == 1)
                {
                    a[i] = 0;
                }
                else
                {
                    a[i] = 1;
                }
            }
        }
    }
    for (i = 1; i < n; i++)
    {
        if (a[i] == 1)
            cout << "第" << i + 1 << "盏灯处于打开状态" << endl;
    }
}

二十七、图3-2所示的圆圈中,把相隔一个数据的两个数称作是“一对数”

编写算法求出乘积最大的一队数和乘积最小的一对数。输出格式如下:
max = ? * ? = ?
min = ? * ? = ?
在这里插入图片描述

#include <iostream>
using namespace std;
int main()
{
    int max = 1, min = 32767, a[100], num, i, k, m, n, s, t, p, q;
    cout << "input a number";
    cin >> num;
    for (i = 0; i < num; i++)
        cin >> a[i];
    for (i = 0; i < num; i++)
    {
        p = (num + i - 1) % num;
        q = (i + 1) % num;
        k = a[p] * a[q];
        if (k > max)
        {
            max = k;
            m = a[p];
            n = a[q];
        }
        if (k < min)
        {
            min = k;
            s = a[p];
            t = a[q];
        }
    }
    cout << "max= " << m << " * " << n << " = " << max << endl;
    cout << "min= " << s << " * " << t << " = " << min << endl;
}

二十八、冒泡排序算法的改进。

#include <iostream>
using namespace std;
int main()
{
    int i, j, t, n, a[100], flag = 1;
    cout << "input data number (<100) :";
    cin >> n;
    cout << "input data :" << endl;
    for (i = 0; i < n; i++)
    {
        cout << i + 1 << " . ";
        cin >> a[i];
    }
    for (i = 1; i <= n - 1 && flag == 1; i++)
    {
        flag = 0;
        for (j = n - 1; j >= i; j--)
        {
            if (a[j] < a[j - 1])
            {
                t = a[j];
                a[j] = a[j - 1];
                a[j - 1] = t;
                flag = 1;
            }
        }
    }
    cout << endl << endl;
    for (i = 0; i < n; i++)
    {
        cout << i + 1 << " . " << a[i] << endl;
    }
}

二十九、编程判定从键盘输入n个数据互不相等。

#include <iostream>
using namespace std;
int main()
{
    int a[100], i, j, t = 1, n;
    cout << "请输入N的值";
    cin >> n;
    for (i = 1; i <= n; i++)
    {
        cout << i << " . ";
        cin >> a[i];
    }
    for (i = 1; i <= n - 1; i++)
    {
        for (j = i + 1; j < n; j++)
        {
            if (a[i] = a[j])
            {
                t = 0;
                break;
            }
        }
    }
    if (t == 1)
        cout << "Non repeat" << endl;
    else
        cout << "repeat" << endl;
}

三十、输入3个数值,判断它们为边长是否能构成三角形。

如能构成,判断属于哪种特殊三角形:等边、等腰或直角。

#include <iostream>
using namespace std;
int main()
{
    int a, b, c, flag;
    cout << "Input 3 number : ";
    cin >> a >> b >> c;
    if (a >= b + c || b >= a + c || c >= a + b)
        cout << "don't form a triangle .";
    else
    {
        flag = 0;
        if (a * a == b * b + c * c || b * b == a * c + c * c || c * c == a * a + b * b)
        {
            cout << "form a right-angle triangle .";
            flag = 1;
        }
        if (a == b && b == c)
        {
            cout << "form a equilateral triangle .";
            flag = 1;
        }
        else if (a == b || a == c || b == c)
        {
            cout << "form a equal haunch triangle .";
            flag = 1;
        }
        if (flag == 0)
        {
            cout << "form a triangle .";
        }
    }
}

三十一、编写算法,求任意3个数的最小公倍数。

#include <iostream>
using namespace std;
int max(int x, int y, int z)
{
    if (x > y && x > z)return(x);
    else if (y > x && y > z)return(y);
    else return(z);
}
int main()
{
    int x1, x2, x3, t = 1, i, flag, x0;
    cout << "Input 3 number :";
    cin >> x1 >> x2 >> x3;
    x0 = max(x1, x2, x3);
    for (i = 2; i <= x0; i++)
    {
        flag = 1;
        while (flag == 1)
        {
            flag = 0;
            if (x1 % i == 0)
            {
                x1 = x1 / i;
                flag = 1;
            }
            if (x2 % i == 0)
            {
                x2 = x2 / i;
                flag = 1;
            }
            if (x3 % i == 0)
            {
                x3 = x3 / i;
                flag = 1;
            }
            if (flag == 1)
                t *= i;
        }
        x0 = max(x1, x2, x3);
    }
    cout << "The result is " << t << endl;
}

三十二、警察局抓了a,b,c,d 4名偷窃嫌疑犯,其中只有一人是小偷。

审问中,
a说:“我不是小偷。”;
b说:“c是小偷。”;
c说:“小偷肯定是d。”;
d说:“c在冤枉人。”;
现在已经知道4个人中3个人说的是真话,一个人说的是假话,问到底谁是小偷?

#include <iostream>
using namespace std;
int main()
{
    int x;
    for (x = 1; x <= 4; x++)
    {
        if ((x != 1) + (x == 3) + (x == 4) + (x != 4) == 3)
        {
            cout << char(64 + x) << " is a thief .";
        }
    }
}

三十三、3位老师对某次数学竞赛进行了预测。

他们的预测如下。
甲说:学生A得第一名,学生B得第三名。
乙说:学生C得第一名,学生D得第四名。
丙说:学生D得第二名,学生A得第三名。
竞赛结果表明,他们都说对了一半,说错了一半,并且无并列名次,试编程输出a,b,c,d 各自的名次。

#include <iostream>
using namespace std;
int main()
{
    int a, b, c, d;
    for (a = 1; a <= 4; a++)
    {
        for (b = 1; b <= 4; b++)
        {
            if (b != a)
            {
                for (c = 1; c <= 4; c++)
                {
                    if (c != a && c != b)
                    {
                        d = 10 - a - c - b;
                        if ((a == 1) + (b == 3) == 1 && (c == 1) + (d == 4) == 1 && (d == 2) + (a == 3) == 1)
                        {
                            cout << "a = " << a << endl;
                            cout << "b = " << b << endl;
                            cout << "c = " << c << endl;
                            cout << "d = " << d << endl;
                        }
                    }
                }
            }
        }
    }
}

三十四、填写运算符。

输入任意五个数x1,x2,x3,x4,x5 每两个相邻数之间填上一个运算符。在填入4个运算符“+、-、*、/”后,使得表达式值为一个指定值y(y由键盘输入)。求出所有满足条件的表达式。

#include <iostream>
using namespace std;
int main()
{
    int j, k, f, i[5], total = 0;
    float n[6], p, q, g;
    char c[5] = { ' ','+','-','*','/' };
    cout << "Input five number ." << endl;
    for (j = 1; j <= 5; j++)
    {
        cout << j << " . ";
        cin >> n[j];
    }
    cout << "Input result : ";
    cin >> n[0];
    for (i[1] = 1; i[1] <= 4; i[1]++)
    {
        if ((i[1] < 4) || (n[2] != 0))
        {
            for (i[2] = 1; i[2] <= 4; i[2]++)
            {
                if ((i[2] < 4) || (n[3] != 0))
                {
                    for (i[3] = 1; i[3] <= 4; i[3]++)
                    {
                        if ((i[3] < 4) || (n[4] != 0))
                        {
                            for (i[4] = 1; i[4] <= 4; i[4]++)
                            {
                                if ((i[4] < 4) || (n[5] != 0))
                                {
                                    p = 0;
                                    q = n[1];
                                    f = 1;
                                    for (k = 1; k <= 4; k++)
                                    {
                                        switch (i[k])
                                        {
                                        case 1:
                                            p = p + f * q;
                                            f = 1;
                                            q = n[k + 1];
                                            break;
                                        case 2:
                                            p = p + f * q;
                                            f = -1;
                                            q = n[k + 1];
                                            break;
                                        case 3:
                                            q = q * n[k + 1];
                                            break;
                                        case 4:
                                            q = q / n[k + 1];
                                        }
                                    }
                                    if (p + f * q == n[0])
                                    {
                                        total++;
                                        cout << endl << "total : " << total << endl;
                                        for (k = 1; k <= 4; k++)
                                            cout << n[k] << c[i[k]];
                                        cout << n[5] << "=" << n[0];
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }
    if (total == 0)
        cout << "Non solution" << endl;
}

三十五、有10箱产品,每箱有1000件,正品每件100克。

其中有几箱是次品,每件次品比正品轻10克,问能否用秤只称一次,就找出哪几箱是次品。
算法设计1:

#include <iostream>
using namespace std;
int main()
{
    int i, k, n, t = 1;
    long w1 = 0, w2;
    cout << "Input the number of boxes : ";
    cin >> n;
    for (i = 1; i <= n; i++)
    {
        cout << i << " box take " << t << " units " << endl;
        w1 += t;
        t *= 2;
    }
    w1 *= 100;
    cout << "Normal weight :" << w1 << endl;
    cout << "Input reality weight : ";
    cin >> w2;
    w1 = (w1 - w2) / 10;
    while (w1 != 0)
    {
        k = 0;
        t = 1;
        while (w1 - t >= 0)
        {
            t *= 2;
            k++;
            cout << k << " box is bad " << endl;
            w1 -= t / 2;
        }
    }
}

算法设计2:

#include <iostream>
using namespace std;
int main()
{
	int i, n, t = 1;
	double w1 = 0, w2, k;
	cout << "Input the number of boxes : ";
	cin >> n;
	for (i = 1; i <= n; i++)
	{
		cout << i << " box take " << t << " letter " << endl;
		w1 += t;
		t *= 2;
	}
	w1 *= 100;
	cout << "Normal weight : " << w1 << endl;
	cout << "Input reality weight : ";
	cin >> w2;
	w1 = (w1 - w2) / 10;
	while (w1 != 0)
	{
		k = log(w1) / log(2);
		cout << k + 1 << " is bad " << endl;
		w1 -= pow(2, k);
	}
}

三十六、编写算法对输入的一个整数,判断它能否被3,5,7整除。

并输出以下信息之一:
能同时被3,5,7整除;
能被其中两个数(要指出哪两个)整除;
能被其中一个数(要指出哪一个)整除;
不能被3,5,7整除。
算法设计1:

#include <iostream>
using namespace std;
int main()
{
	long n;
	int k;
	cout << "Please enter a number : ";
	cin >> n;
	k = ((n % 3) == 0) + ((n % 5) == 0) + ((n % 7) == 0);
	switch (k)
	{
	case 0:
		cout << "None" << endl;
		break;
	case 1:
		cout << "0ne" << endl;
		break;
	case 2:
		cout << "Two" << endl;
		break;
	case 3:
		cout << "All" << endl;
		break;
	}
}

算法设计2:

#include <iostream>
using namespace std;
int main()
{
	long n;
	int k;
	cout << "Please enter a number : ";
	cin >> n;
	k = ((n % 3) == 0) + ((n % 5) == 0) * 2 + ((n % 7) == 0) * 4;
	switch (k)
	{
	case 7:
		cout << "可被 All 整除" << endl;
		break;
	case 6:
		cout << "可被 5 and 7 整除" << endl;
		break;
	case 5:
		cout << "可被 3 and 7 整除" << endl;
		break;
	case 4:
		cout << "可被 7 整除" << endl;
		break;
	case 3:
		cout << "可被 3 and 5 整除" << endl;
		break;
	case 2:
		cout << "可被 5 整除" << endl;
		break;
	case 1:
		cout << "可被 3 整除" << endl;
		break;
	case 0:
		cout << "None" << endl;
		break;
	}
}

三十七、求n次二项式各项的系数,已知二项式的展开式为:

(a+b)n=C0aan+C1aan-1b+C2aan-2b2+…+Cnnbn

#include <iostream>
using namespace std;
void coeff(int a[], int n)
{
	int i;
	if (n == 1)
	{
		a[1] = 1;
		a[2] = 1;
	}
	else
	{
		coeff(a, n - 1);
		a[n + 1] = 1;
		for (i = n; i >= 2; i--)
			a[i] = a[i] + a[i - 1];
		a[1] = i;
	}
}
int main()
{
	int a[100], i, n;
	cout << "请输入N的值:";
	cin >> n;
	for (i = 1; i <= n; i++)
	{
		cout << i << " . ";
		cin >> a[i];
	}
	coeff(a, n);
	for (i = 1; i <= n; i++)
		cout << a[i];
}

三十八、数组中有n个数据。

要将它们顺序循环向后移k位,即前面的元素向后移k位,后面的元素则循环向前移k位,例:0,1,2,3,4 循环移3位后为 2,3,4,0,1。后考虑到n会很大,不允许用2×n以上个空间来完成此题。
算法设计1:

#include <iostream>
using namespace std;
int main()
{
	int a[100], b[100], i, n, k;
	cout << "请输入数据长度";
	cin >> n;
	cout << "请输入移动距离";
	cin >> k;
	for (i = 0; i < n; i++)
	{
		cout << i + 1 << " . ";
		cin >> a[i];
	}
	for (i = 0; i < n; i++)
		b[(k + i) % n] = a[i];
	for (i = 0; i < n; i++)
		cout << b[i] << " ";
}

算法设计2:

#include <iostream>
using namespace std;
int main()
{
	int a[100], i, j, n, k, temp;
	cout << "请输入数据长度";
	cin >> n;
	cout << "请输入移动距离";
	cin >> k;
	for (i = 0; i < n; i++)
	{
		cout << i + 1 << " . ";
		cin >> a[i];
	}
	for (i = 0; i < k; i++)
	{
		temp = a[n - 1];
		for (j = n - 1; j > 0; j--)
			a[j] = a[j - 1];
		a[0] = temp;
	}
	for(i=0;i<n;i++)
		cout << a[i] << " ";
}

算法设计3:

#include <iostream>
using namespace std;
int ff(int a, int b)
{
	int i, t = 1;
	for (i = 2; i <= a && i <= b; i++)
	{
		while (a % i == 0 && b % i == 0)
		{
			t *= i;
			a /= i;
			b /= i;
		}
	}
	return t;
}
int main()
{
	int a[100], b0, b1, i, j, n, k, m, tt;
	cout << "请输入数据长度";
	cin >> n;
	cout << "请输入移动距离";
	cin >> k;
	for (i = 0; i < n; i++)
	{
		cout << i + 1 << " . ";
		cin >> a[i];
	}
	m = ff(n, k);
	for (j = 0; j < m; j++)
	{
		b0 = a[j];
		tt = j;
	}
	for (i = 0; i < n / m; i++)
	{
		tt = (tt + k) % n;
		b1 = a[tt];
		a[tt] = b0;
		b0 = b1;
	}
	for (i = 0; i < n; i++)
		cout << a[i] << " ";
}

三十九、编写算法完成下面给“余”猜数的游戏。

心里先想好一个1~100之间的整数x,将它分别除以3,5和7并得到3个余数。把这3个余数输入计算机,计算机能马上猜出这个数。游戏过程如下:
Please think of a number between 1 and 100
Your number divided by 3 has a remainder of 1
Your number divided by 5 has a remainder of 0
Your number divided by 7 has a remainder of 5
let me think a moment …
Your number was 40

#include <iostream>
using namespace std;
int main()
{
	int a, b, c, d;
	cout << "Please think of a number between 1 and 100" << endl;
	cout << "Your number divided by 3 has a remainder of ";
	cin >> a;
	cout << "Your number divided by 5 has a remainder of ";
	cin >> b;
	cout << "Your number divided by 7 has a remainder of ";
	cin >> c;
	cout << "let me think a moment ..." << endl;
	d = 70 * a + 21 * b + 15 * c;
	if (d > 105)
		d -= 105;
	cout << "Your number was " << d << endl;
}

四十、楼梯上有n级台阶,上楼时可以一步上1阶,也可以一步上2阶。

编写算法计算共有多少种不同的上楼梯方法。

#include <iostream>
using namespace std;
int f(int n)
{
	if (n == 1)
		return 1;
	if (n == 2)
		return 2;
	else
		return(f(n - 1) + f(n - 2));
}
int main()
{
	int n;
	cout << "n = ";
	cin >> n;
	cout << "f( " << n << " ) = " << f(n) << endl;
}

四十一、核反应堆中有α和β两种粒子。

每秒钟内一个α例子变化为三个β粒子,而一个β粒子可以变化为一个α粒子和两个β粒子。若在t=0时刻,反应堆中只有一个α粒子,求在t时刻的反应堆中α粒子和β粒子数。
算法设计1:

#include <iostream>
using namespace std;
int main()
{
	int n[100], m[100], t, i;
	cout << "请输入时刻 ( t )";
	cin >> t;
	n[0] = 1;
	m[0] = 0;
	for (i = 1; i <= t; i++)
	{
		n[i] = m[i - 1];
		m[i] = 3 * n[i - 1] + 2 * m[i - 1];
	}
	cout << " α: " << n[t];
	cout << " β: " << m[t];
}

算法设计2:

#include <iostream>
using namespace std;
int main()
{
	int t, i, n, m;
	cout << "请输入时刻 ( t )";
	cin >> t;
	n = int(exp(t * log(3)));
	m = int(exp((t + 1) * log(3)));
	if (t % 2 == 1)
	{
		n -= 3;
		m += 3;
	}
	else
	{
		n += 3;
		m -= 3;
	}
	n = n / 4;
	m = m / 4;
	cout << " α: " << n;
	cout << " β: " << m;
}

The End

  • 12
    点赞
  • 88
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

WiChP

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值