完善程序技巧
一、须知
1. 分类
- 模拟题(字符串、数组等,思路拐来拐去)
- 算法模板题(
gcd
、质因数分解、贪心、枚举等) - 基础算法延伸题(一道新的题,看懂程序,排除法选选项)
2. 技巧
- 模板一定要牢记,否则一上场就得嗝了。
- 换种写法你就不会了,那也嘎了。
二、基础例题
1. 2020 CSP-J T19 质因数分解
(质因数分解)给出正整数
n
n
n,请输出将
n
n
n 质因数分解的结果,结果从小到大输出。
例如:输入
n
=
120
n=120
n=120,程序应该输出
2
2
2
3
5
2\ 2\ 2\ 3\ 5
2 2 2 3 5,表示:
120
=
2
×
2
×
2
×
3
×
5
120=2×2×2×3×5
120=2×2×2×3×5。输入保证
2
≤
n
≤
1
0
9
2≤n≤10^9
2≤n≤109。
提示:先从小到大枚举变量 i i i,然后用 i i i 不停试除 n n n 来寻找所有的质因子。
试补全程序。
#include <cstdio>
using namespace std;
int n, i;
int main() {
scanf("%d", &n);
for(i = ①; ② <=n; i ++){
③{
printf("%d ", i);
n = n / i;
}
}
if(④)
printf("%d ", ⑤);
return 0;
}
-
①
①
① 处应填(
C
C
C)
A.1
B.n-1
C.2
D.0
-
②
②
② 处应填(
C
C
C)
A.n/i
B.n/(i*i)
C.i*i
D.i*i*i
-
③
③
③ 处应填(
C
C
C)
A.if(n%i==0)
B.if(i*i<=n)
C.while(n%i==0)
D.while(i*i<=n)
-
④
④
④ 处应填(
A
A
A)
A.n>1
B.n<=1
C.i<n/i
D.i+i<=n
-
⑤
⑤
⑤ 处应填(
C
C
C)
A.2
B.n/i
C.n
D.i
2. 2017 普及组 T27 快速幂
(快速幂) 请完善下面的程序,该程序使用分治法求 x p m o d m x^p \mod m xpmodm 的值。
输入:三个不超过
10000
10000
10000 的正整数
x
,
p
,
m
x,p,m
x,p,m。
输出:
x
p
m
o
d
m
x^p \mod m
xpmodm 的值。
提示:若
p
p
p 为偶数,
x
p
=
(
x
2
)
p
÷
2
x^p=(x^2)^{p\div 2}
xp=(x2)p÷2;若
p
p
p 为奇数,
x
p
=
x
×
(
x
2
)
(
p
−
1
)
÷
2
x^p=x\times(x^2)^{(p-1)\div 2}
xp=x×(x2)(p−1)÷2。
#include<iostream>
using namespace std;
int x, p, m, i, result;
int main(){
cin >> x >> p >> m;
result = ①;
while (②){
if (p % 2 == 1)
result = ③;
p /= 2;
x = ④;
}
cout << ⑤ << endl;
return 0;
}
1
p>0
/ / /p!=0
/ / /p
result*x%m
x*x%m
result
3. 2022 CSP-J T19 枚举因数
(枚举因数)从小到大打印正整数
n
n
n 的所有正因数。
试补全枚举程序。
#include <bits/stdc++.h>
using namespace std;
int main(){
int n;
cin >> n;
vector<int> fac;
fac.reserve((int)ceil(sqrt(n)));
int i;
for (i = 1; i * i < n; ++i){
if (①){
fac.push_back(i);
}
}
for (int k = 0; k < fac.size(); ++k){
cout << ② << "";
}
if (③) {
cout << ④ << "";
}
for (int k = fac.size() - 1; k >= 0; --k){
cout << ⑤ << "";
}
}
-
①
①
① 处应填(
A
A
A)
A.n % i == 0
B.n % i == 1
C.n % (i-1) == 0
D.n % (i-1) == 1
-
②
②
② 处应填(
B
B
B)
A.n / fac[k]
B.fac[k]
C.fac[k]-1
D.n / (fac[k]-1)
-
③
③
③ 处应填(
C
C
C)
A.(i-1)*(i-1)== n
B.(i-1)*i == n
C.i*i == n
D.i*(i-1) == n
-
④
④
④ 处应填(
D
D
D)
A.n-i
B.n-i+1
C.i-1
D.i
-
⑤
⑤
⑤ 处应填(
A
A
A)
A.n / fac[k]
B.fac[k]
C.fac[k]-1
D.n / (fac[k]-1)
三、难题
1. 2019 CSP-J T.19
(矩阵变幻)有一个奇幻的矩阵,在不停的变幻,其变幻方式为:
数字 0
变成矩阵
0 0
0 1
数字 1
变成矩阵
1 1
1 0
最初该矩阵只有一个元素 0
,变幻 n
次后,矩阵会变成什么样?
例如,矩阵最初为:
0
矩阵变幻 1 1 1 次后:
0 0
0 1
矩阵变幻 2 2 2 次后:
0 0 0 0
0 1 0 1
0 0 1 1
0 1 1 0
输入一行一个不超过 10 10 10 的正整数 n n n。输出变幻 n n n 次后的矩阵。试补全程序。
提示:
<<
表示二进制左移运算符
而 ^
表示二进制异或运算符,它将两个参与运算的数中的每个对应的二进制位—进行比较,若两个二进制位相同,则运算结果的对应二进制位为
0
0
0,反之为
1
1
1。
#include <cstdio>
using namespace std;
int n;
const int max_size = 1 << 10;
int res[max_size][max_size];
void recursive(int x, int y, int n, int t) {
if (n == 0) {
res[x][y] = ①;
return;
}
int step = 1 << (n - 1);
recursive(②, n - 1, t);
recursive(x, y + step, n - 1, t);
recursive(x + step, y, n - 1, t);
recursive(③, n - 1, !t);
}
int main() {
scanf("%d", &n);
recursive(0, 0, ④);
int size = ⑤;
for (int i = 0; i < size; i++) {
for (int j = 0; j < size; j++)
printf("%d", res[i][j]);
puts("");
}
return 0;
}
-
①
①
① 处应填(
C
C
C)
A.n%2
B.0
C.t
D.1
-
②
②
② 处应填(
D
D
D)
A.x-step,y-step
B.x,y-step
C.x-step,y
D.x,y
-
③
③
③ 处应填(
B
B
B)
A.x-step,y-step
B.x+step,y+step
C.x-step,y
D.x,y-step
-
④
④
④ 处应填(
B
B
B)
A.n-1,n%2
B.n,0
C.n,n%2
D.n-1,0
-
⑤
⑤
⑤ 处应填(
B
B
B)
A.1<<(n+1)
B.1<<n
C.n+1
D.1<<(n-1)