C++算法设计与分析例题代码
- 前言
- 一、求1/1!-1/3!+1/5!-1/7!+...+(-1)^(n+1)/(2n-1)!
- 二、一个数如果恰好等于它的因子之和(包括1,但不包含这个数本身),这个数就称为完数。
- 三、求一个矩阵的鞍点,即在行上最小而在列上最大的点。
- 四、编写算法:
- 五、汉诺塔问题:
- 六、整数的分划问题。
- 七、任给十进制的正整数,请从低位到高位逐位输出各位数字。
- 八、任给十进制的正整数,请从高位到低位逐位输出各位数字。
- 九、任何一个正整数都可以用2的幂次方表示。
- 十、找出n个自然数(1,2,3,...,n)中取r个数的组合。
- 十一、某校决定由全校学生选举自己的学生会主席。
- 十二、编程统计身高(单位为厘米)。
- 十三、一次考试共考了语文、代数和外语3科。
- 十四、编写算法将数字序号“翻译”成英文符号。
- 十五、一个顾客买了价值x元的商品(不考虑角、分),并将y元的钱交给售货员。
- 十六、求x使x^2^为一个各位数字互不相同的9位数。
- 十七、游戏问题:
- 十八、高精度数据×长整数。
- 十九、编程求当n<=100时,n!的准确值。
- 二十、编程打印有如下规律的n×n方阵。
- 二十一、螺旋阵:任意给定n值,按如下螺旋的方式输出方阵。
- 二十二、魔方阵是我国古代发明的一种数字游戏:
- 二十三、统计问题:找链环数字对的出现频率。
- 二十四、有3n个花盆,红色、蓝色和黄色的各n个。
- 二十五、一次考试,共考了五门课。
- 二十六、开灯问题:
- 二十七、图3-2所示的圆圈中,把相隔一个数据的两个数称作是“一对数”
- 二十八、冒泡排序算法的改进。
- 二十九、编程判定从键盘输入n个数据互不相等。
- 三十、输入3个数值,判断它们为边长是否能构成三角形。
- 三十一、编写算法,求任意3个数的最小公倍数。
- 三十二、警察局抓了a,b,c,d 4名偷窃嫌疑犯,其中只有一人是小偷。
- 三十三、3位老师对某次数学竞赛进行了预测。
- 三十四、填写运算符。
- 三十五、有10箱产品,每箱有1000件,正品每件100克。
- 三十六、编写算法对输入的一个整数,判断它能否被3,5,7整除。
- 三十七、求n次二项式各项的系数,已知二项式的展开式为:
- 三十八、数组中有n个数据。
- 三十九、编写算法完成下面给“余”猜数的游戏。
- 四十、楼梯上有n级台阶,上楼时可以一步上1阶,也可以一步上2阶。
- 四十一、核反应堆中有α和β两种粒子。
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