您的位置:首页 > 其它

《算法竞赛入门经典》(第2版)第二章习题

2015-10-26 07:40 411 查看
本文部分习题参考了litiouslove的blog:

http://blog.csdn.net/litiouslove/article/details/7891700

习题2-1 水仙花数(daffodil)

输出100~999中的所有水仙花数。若3位数ABC满足ABC=A3+B3+C3,则称其为水仙花数。例如153=13+53+33,所以153是水仙花数。

#include<iostream>
using namespace std;

int main()
{
int n;
for (n = 100; n < 1000; n++)
{
int hundred = n / 100;
int decade = n / 10 % 10;
int digit = n % 10;
if (n == (hundred*hundred*hundred + decade*decade*decade + digit*digit*digit))
{
cout << "daffodile number: " << n << "\n";
}
}
}

/*
daffodile number: 153
daffodile number: 370
daffodile number: 371
daffodile number: 407
*/


习题2-2 韩信点兵(hanxin)

相传韩信才智过人,从不直接清点自己军队的人数,只要让士兵先后以三人一排、五人一排、七人一排地变换队形,而他每次只掠一眼队伍的排尾就知道总人数了。输入包含多组数据,每组数据包含3个非负整数a,b,c,表示每种队形排尾的人数(a<3,b<5,c<7),输出总人数的最小值(或报告无解)。已知总人数不小于10,不超过100。输入到文件结束为止。

样例输入:

2 1 6

2 1 3

样例输出:

Case 1: 41

Case 2: No answer

#include<iostream>
using namespace std;

int main()
{
int a, b, c, i, kase = 0;
while (cin >> a >> b >> c)
{
kase++;
i = 0;
for (i = 10; i <= 100; i++)
{
if ((i % 3 == a) && (i % 5 == b) && (i % 7 == c))
{
cout << "Case " << kase << ": " << i << "\n";
break;
}
}
if (i > 100)
{
cout << "Case " << kase << ": " << "No answer" << "\n";
}

}
}
/*
2 1 6
Case 1: 41
2 1 3
Case 2: No answer
0 0 0
Case 3: No answer
1 0 0
Case 4: 70
1 2
3
Case 5: 52

*/


习题2-3 倒三角形(triangle)

输入正整数n≤20,输出一个n层的倒三角形。例如,n=5时输出如下:

#########
#######
#####
###
#


#include<iostream>
using namespace std;

int main()
{
int n, i, j;
cin >> n;
if (n < 1 || n > 20)
{
cout << "Out of range[1, 20]\n";
return -1;
}

for (i = n; i > 0; i--)
{
for (j = 0; j < n - i; j++) cout << " ";
for (j = 0; j < 2*i-1; j++) cout << "#";
cout << "\n";
}
}


习题2-4 子序列的和(subsequence)

输入两个正整数n<m<10^6,输出1/n^2 + 1/(n+1)^2 + …… + 1/m^2,保留5位小数。输入包含多组数据,结束标记为n=m=0。提示:本题有陷阱。

样例输入:

2 4

65536 655360

0 0

样例输出:

Case 1: 0.42361

Case 2: 0.00001

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

int main()
{
int n, m, kase = 0;
double result;
while (cin >> n >> m)
{
if (n == 0 && m == 0)
{
break;
}
if (n >= m || n < 0 || m >= pow(10, 6))
{
cout << "Invalid input: Expected (0, 10^6), but n=" << n << ", m=" << m << endl;
return -1;
}
result = 0;
for (int i = n; i <= m; i++)
{

result += (double)1/i/i;

}

kase++;
cout << "Case " << kase << ": " << setprecision(5) << fixed << result << endl;
}

return 0;
}


(陷阱就是在n特别大时如果直接n*n就会溢出,所以只能连除两次)

习题2-5 分数化小数(decimal)

输入正整数a,b,c,输出a/b的小数形式,精确到小数点后c位。a,b≤10^6,c≤100。输入包含多组数据,结束标记为a=b=c=0。

样例输入:

1 6 4

0 0 0

样例输出:

Case 1: 0.1667

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

int main()
{
int a, b, c, remainder, kase = 0;
while (cin >> a >> b >> c)
{
if (a == 0 && b == 0 && c == 0)
{
break;
}
if (a < 0 || b < 0 || c < 0
|| a > pow(10, 6) || b > pow(10,6) || c > 100)
{
cout << "Invalid input: Expected a, b: (0, 10^6], c: (0, 100], but a="
<< a << ", b=" << b << ", c=" << c << endl;
return -1;
}

kase++;
cout << "Case " << kase << ": " << a/b << ".";
remainder = a%b;
for (int i = 1; i < c; i++)
{
cout << remainder*10/b;
remainder = remainder*10%b;
}
cout << remainder*10/b + (remainder*10/b+5)/10 << endl;
}
return 0;
}


(本题的解法是有问题的,尚不能解决尾数是9的时候4舍5入的问题。留给以后再想办法。。)

习题2-6 排列(permutation)

用1,2,3,…,9组成3个三位数abc,def和ghi,每个数字恰好使用一次,要求abc:def:ghi=1:2:3。按照“abc def ghi”的格式输出所有解,每行一个解。提示:不必太动脑筋。

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

int is_valid_number(int num, int array[])
{
int x, y, z;
x = num / 100;
y = num / 10 % 10;
z = num % 10;
if (x == y || y == z || array[x] || array[y] || array[z]) {
// Digit used
return 0;
}
array[x] = array[y] = array[z] = 1;
return 1;
}

int main()
{
int array[10];
array[0] = 1;
for (int checked_num = 123; checked_num < 329; checked_num++ )
{
for (int i = 1; i < 10; i++)
array[i] = 0;
if (is_valid_number(checked_num, array)
&& is_valid_number(checked_num*2, array)
&& is_valid_number(checked_num*3, array))
{
cout << checked_num << ":" << checked_num*2 << ":" << checked_num*3 << endl;
}
}
cout << clock() << endl;
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: