【题解】 —算法竞赛入门经典第二版 【第七章例题】【4/15】

UVa 725 Division【枚举】

题目大意:

输入$n(2 \leq n \leq 79)$,从小到大输出所有形如$abcde / fghij = n$的表达式,其中a ~ j恰好为数字0 ~ 9的一个排列(可以有前导零)。

解题思路:

  • 枚举每个数的取值?复杂度$O(10!)$,不可以。
  • 观察这个式子我们可以变形为$abcde = n \times fghij$,这时候直接枚举$fghij$的值,就可以计算出$abcde$的值了,然后判断是否0 ~ 9这些数字都出现过。
  • 再根据$n$的取值范围,我们可以缩小$fghij$的取值范围了,下界为1234,上界为98765 / 2,即范围为$1234$~$49382$,实际上还可以更小,不过到这里问题就可以解决了。

MyCode:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
#include <cstdio>
#include <iostream>
#include <cstring>
#include <algorithm>
#include <cmath>
using namespace std;

int n;
char num[11] = "0123456789";
char tem[11];
int main()
{
int cas = 0;
while(scanf("%d", &n) && n)
{
if(cas) puts("");
bool flag = 0;
for(int fghij = 1234; fghij <= 49382; ++fghij)
{
int abcde = fghij * n;
if(abcde > 98765) break;
if(fghij > 10000)
sprintf(tem, "%d%d", abcde, fghij);
else
sprintf(tem, "%d%d%d", abcde, fghij, 0);
sort(tem, tem + 10);
if(strcmp(tem, num) == 0)
{
flag = 1;
printf("%d / %05d = %d\n", abcde, fghij, n);
}
}
if(!flag)
printf("There are no solutions for %d.\n", n);
++cas;
}
return 0;
}

UVa 11059 Maximum Product【枚举】

题目大意:

给出一个序列,求出一个乘积最大的连续子序列,若乘积为负,则答案为0.

解题思路:

枚举起点和终点。

MyCode:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
#include <cstdio>
#include <iostream>
#include <cstring>
#include <algorithm>
#include <cmath>
using namespace std;

int n, cou, a[18];
long long ans, tem;
int main()
{
while(~scanf("%d",&n))
{
ans = 0;
for(int i = 0; i < n; ++i)
scanf("%d",&a[i]);
for(int i = 0; i < n; ++i)
{
tem = 1;
for(int j = i; j < n; ++j)
{
tem *= a[j];
if(tem > ans) ans = tem;
}
}
printf("Case #%d: The maximum product is %lld.\n\n",++cou,ans);
}
return 0;
}

UVa 10976 Fractions Again?!【枚举】

题目大意:

给出一个数$k$,求出有多少对$(x, y)$,满足$\frac{1}{k} = \frac{1}{x} + \frac{1}{y}$且$x \geq y > 0$。

解题思路:

将上述条件联立,对式子变形得,$y \leq 2k \leq x$。这样,在$k+1$ ~ $2k$范围内枚举$y$,然后根据$y$计算出$x$来就可以了($x = \frac{ky}{y-k}$)。

MyCode:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
#include <cstdio>
#include <iostream>
#include <cstring>
#include <algorithm>
#include <cmath>
using namespace std;

int a[10005][5];
int k, tot, tem;
int main()
{
while(~scanf("%d",&k))
{
tot = 0;
for(int y = k + 1; y <= 2 * k; ++y)
{
int tem = k * y / (y - k);
if(tem * (y - k) == k * y)
{
a[tot][0] = tem;
a[tot][1] = y;
tot++;
}
}
cout << tot << endl;
for(int i = 0; i < tot; ++i)
printf("1/%d = 1/%d + 1/%d\n",k,a[i][0],a[i][1]);
}
return 0;
}

UVa 524 Prime Ring Problem【回溯】

题目大意:

输入n个数,将这n个数组成一个环,使得相邻两数之和均为素数。

解题思路:

DFS + 剪枝。

MyCode:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
#include <cstdio>
#include <iostream>
#include <cstring>
#include <algorithm>
#include <cmath>
using namespace std;

int n, a[22];
bool pri[33], used[22];

void init()
{
pri[2] = pri[3] = pri[5] = pri[7] = 1;
pri[11] = pri[13] = pri[17] = pri[19] = 1;
pri[23] = pri[29] = pri[31] = 1;
}

void DFS(int cur)
{
if(cur == n + 1)
{
if(!pri[a[1] + a[n]]) return ;
for(int i = 1; i <= n; ++i)
printf("%d%c", a[i], i == n ? '\n' : ' ');
return ;
}
for(int i = 2; i <= n; ++i)
{
if(!used[i] && pri[a[cur - 1] + i])
{
used[i] = 1;
a[cur] = i;
DFS(cur + 1);
used[i] = 0;
}
}
}

int main()
{
init();
for(int cas = 1; ~scanf("%d", &n); ++cas)
{
if(cas > 1) puts("");
printf("Case %d:\n", cas);
a[1] = 1;
used[1] = 1;
DFS(2);
}
return 0;
}

UVa 129 Krypton Factor【】

题目大意:

解题思路:

MyCode:

1
2


UVa

题目大意:

解题思路:

MyCode:

1
2


UVa

题目大意:

解题思路:

MyCode:

1
2


UVa

题目大意:

解题思路:

MyCode:

1
2


UVa

题目大意:

解题思路:

MyCode:

1
2


UVa

题目大意:

解题思路:

MyCode:

1
2


UVa

题目大意:

解题思路:

MyCode:

1
2


UVa

题目大意:

解题思路:

MyCode:

1
2


UVa

题目大意:

解题思路:

MyCode:

1
2


UVa

题目大意:

解题思路:

MyCode:

1
2


UVa

题目大意:

解题思路:

MyCode:

1
2


###

Donate comment here
0%