CCF-CSP2023等级认证题解

T1 仓库规划

rx4z17.png

这道题数据量较小,只需要遍历一遍就可以了

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
#include <iostream>
using namespace std;
int n, m;
int a[1005][11];
int main()
{
cin >> n >> m;
for (int i = 1; i <= n; i++)
for (int j = 1; j <= m; j++)
cin >> a[i][j];
for (int i = 1; i <= n; i++)
{
bool do_have = false;//是否存在上级仓库
for (int j = 1; j <= n; j++)
{
bool flag = true;//仓库j是否是i的上级仓库
for (int k = 1; k <= m; k++)
{
if (a[j][k] <= a[i][k])
{
flag = false;
break;
}
}
if (flag)
{
do_have = true;
cout << j << endl;
break;
}
}
if (do_have == false)
cout << 0 << endl;
}
return 0;
}

T2 因子化简

l4cu96.png

这道题考察分解质因数

分解质因数:

做法:对于待分解的数$x$,我们只需要从小到大遍历所有可能的因数,可以被x整除则一直除以此因数,直至$x$被分解完毕。

解释:我们知道,任何数都可以被分解为若干质因数,那么,在从小到大遍历因数时,所有非质因数都已经被分解为质因数。

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
#include <iostream>
#include <cmath>
#include <map>
#define ll long long
using namespace std;
ll Q;
map<ll, ll> bucket;
ll query(ll n, ll k)
{
ll sum = 1;
for (int i = 2; n != 1; i++)
{
while (n % i == 0)
{
bucket[i]++;
n /= i;
}
if (bucket[i] >= k)
sum *= pow(i, bucket[i]);
}
return sum;
}
int main()
{
cin >> Q;
for (ll q = 1; q <= Q; q++)
{
ll n, k;
cin >> n >> k;
cout << query(n, k) << endl;
bucket.clear();
}
return 0;
}

这里需要提醒一下:对于数据

1
10000000000 10

倘若输出结果为1024,原因在于判断n==1终止循环时,此时因子5虽然加到了10,但是无法进行判断,于是所有因数5被舍去,导致答案错误。

错误代码如下:

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

ll Q;
map<ll, ll> bucket;
ll query(ll n, ll k)
{
ll sum = 1;
for (ll i = 2; n != 1;)
{
if (n % i == 0)
{
bucket[i]++;
n /= i;
}
else
{
if (bucket[i] >= k)
{
cout << "i=" << i << " " << bucket[i] << endl;
sum *= pow(i, bucket[i]);
}
i++;
}
}
return sum;
}

T3 树上搜索

ctdp10.png