考试范围
三级标准:
- 掌握算法以及算法性能、算法效率的概念;
- 掌握基本算法中枚举的概念;
- 掌握基本算法中递归的概念;
- 掌握自调用函数的应用,实现基本算法中的递归方法;
- 掌握基本算法中由递归变递推的方法。 能够使用上述方法编写指定功能的正确完整的程序。
章节 1. 枚举算法
P760. 找最大值
#include <bits/stdc++.h>
using namespace std;
int main(){
#ifdef LOCAL
freopen("t1.in", "r", stdin);
#endif
int n;
scanf("%d", &n);
int sum_max = 0;
for(int i = 0; i <= n; i++){
for(int j = 0; j <= n; j++){
for(int k = 0; k <= n; k++){
int x1 = (i + j + k) % 5;
int x2 = (i + j) % 2;
int x3 = (j + k) % 3;
if(x1 == 0 and x2 == 0 and x3 == 0){
sum_max = max(sum_max, i + j + k);
}
}
}
}
printf("%d", sum_max);
return 0;
}
P761. 鸡兔同笼
#include <bits/stdc++.h>
using namespace std;
int main(){
int foot;
scanf("%d", &foot);
int max_animal = 0;
int min_animal = 32768;
for(int i = 0; i <= foot / 2; i++){ //鸡数
for(int j = 0; j <= foot / 2; j++){//兔子数
int t_foot = i * 2 + j * 4;
if(t_foot > foot){
break;
}
if(t_foot == foot){
max_animal = max(max_animal , i + j);
min_animal = min(min_animal , i + j);
}
}
}
if(min_animal == 32768){
min_animal = 0;
}
printf("%d %d", min_animal, max_animal);
return 0;
}
P762. 两倍
#include <bits/stdc++.h>
using namespace std;
int main(){
#ifdef LOCAL
freopen("P762.in", "r", stdin);
#endif
int a[20];
int b[100];
int a_len;
memset(a, 0, sizeof(a));
memset(b, 0, sizeof(b));
int x;
for(int i = 0; i < 20; i++){
scanf("%d", &x);
if(x == 0){
a_len = i;
break;
}else{
a[i] = x;
b[x] = 1;
}
}
int cnt = 0;
for(int i = 0; i < a_len; i++){
int a2 = a[i] * 2;
if(a2 > 100) continue;
if(b[a2] == 1){
cnt = cnt + 1;
}
}
printf("%d", cnt);
return 0;
}
P763. 完美立方
#include<stdio.h>
int main()
{
int n;
scanf("%d",&n);
int a,b,c,d;a,b,c,d均大于1,且b<=c<=d
for(a=2;a<=n;a++)
for(b=2;b<a;b++)
for(c=b;c<a;c++)
for(d=c;d<a;d++)
if(a*a*a==b*b*b+c*c*c+d*d*d){
printf("Cube = %d, Triple = (%d,%d,%d)\n",a,b,c,d);
}
return 0;
}
P771. 和数
#include <bits/stdc++.h>
using namespace std;
int n;
int* a;
int ans;
map<int, int> b;
vector<int> path;
void backtrack(int start){
if(path.size() == 2){
int sum2 = path[0] + path[1];
if(b.count(sum2) == 1){
ans = ans + 1;
}
return;
}
for(int i = start; i < n; i++){
path.push_back(a[i]);
backtrack(i + 1);
path.pop_back();
}
}
int main(){
#ifdef LOCAL
freopen("P771.in", "r", stdin);
#endif
scanf("%d", &n);
a = new int[n + 1];
for(int i = 0; i < n; i++){
scanf("%d", &a[i]);
b[a[i]] = 1;
}
ans = 0;
backtrack(0);
printf("%d", ans);
return 0;
}
P772. 因子问题
#include <bits/stdc++.h>
using namespace std;
int main(){
int N, M;
scanf("%d%d", &N, &M);
for(int a = 2; a < N; a++){
if(N % a == 0){
if(N % (M - a) == 0){
printf("%d", a);
return 0;
}
}
}
printf("%d", -1);
return 0;
}
P773. 潜在朋友
#include <bits/stdc++.h>
using namespace std;
int main(){
int N, M;
scanf("%d%d", &N, &M);
//user_list[用户编号] = 图书编号
int* user_list = new int[N + 1];
memset(user_list, 0, sizeof(user_list));
//book_list[图书编号] = 用户数量
int* book_list = new int[M + 1];
memset(book_list, 0, sizeof(book_list));
for(int i = 0; i < N; i++){
int t;
scanf("%d", &t);
user_list[i] = t;
book_list[t] = book_list[t] + 1;
}
for(int i = 0; i < N; i++){
int count = book_list[user_list[i]];
if(count < 2){
printf("BeiJu\n");
}else{
printf("%d\n", count - 1);
}
}
return 0;
}
P774. 最简真分数
#include <bits/stdc++.h>
using namespace std;
int main(){
int n;
scanf("%d", &n);
int a[610];
memset(a, 0, sizeof(a));
int t;
for(int i = 0; i < n; i++){
scanf("%d", &t);
a[i] = t;
}
sort(a, a + n);
int count = 0;
for(int i = 0; i < n; i++){
for(int j = i + 1; j < n; j++){
if(__gcd(a[i], a[j]) == 1){
if(a[i] < a[j]){
//printf("[%d,%d]", a[i], a[j]);
count++;
}
}
}
}
printf("%d", count);
return 0;
}
P775. 找和为K的两个元素
#include <bits/stdc++.h>
using namespace std;
int main(){
int n, k;
scanf("%d%d", &n, &k);
map<int, int> m;
int* numlist = new int[n + 1];
for(int i = 0; i < n; i++){
int t;
scanf("%d", &t);
m[t] = i;
numlist[i] = t;
}
for(int i = 0; i < n; i++){
int b = k - numlist[i];
if(m.count(b) == 1){
if(m[b] != i){
printf("yes");
return 0;
}
}
}
printf("no");
return 0;
}
P780. 最接近的分数
#include <bits/stdc++.h>
using namespace std;
int main(){
int N, A,B;
int max_A = 0;
int max_B = 0;
double max_AB = 0;
scanf("%d%d%d", &N, &A, &B);
double AB = 1.0 * A / B;
for(int i = 1; i < N; i++){
for(int j = i + 1; j < N; j++){
double t_AB = 1.0 * i / j;
if(t_AB < AB && max_AB < t_AB){
max_A = i;
max_B = j;
max_AB = t_AB;
break;
}
}
}
printf("%d %d", max_A, max_B);
return 0;
}
章节 2. 递推算法
P517. 走楼梯
//https://www.mfstem.org/p/517
#include <bits/stdc++.h>
using namespace std;
int main(){
int N;
scanf("%d", &N);
int dp[50];
memset(dp, 0, sizeof(dp));
dp[1] = 1;
dp[2] = 2;
//每阶楼梯的走法数是前两个楼梯之和
for(int i = 3; i <= N; i++){
dp[i] = dp[i - 1] + dp[i - 2];
}
printf("%d", dp[N]);
return 0;
}
P518. 兔子繁殖
#include <bits/stdc++.h>
using namespace std;
int main(){
int N;
scanf("%d", &N);
long dp[50][3]; //注意不能int,数字太大溢出
memset(dp, 0, sizeof(dp));
//0--小兔子数,1--大兔子数
dp[1][0] = 2;
dp[1][1] = 0;
for(int i = 2; i <= N; i++){
dp[i][0] = dp[i - 1][1];//小兔子出生
dp[i][1] = dp[i - 1][0] + dp[i - 1][1];//小兔子变大兔子
}
long X = dp[N][0] + dp[N][1];
printf("%d", X / 2);
return 0;
}
P519. 平面分割
P520. 骨牌铺法
#include <bits/stdc++.h>
using namespace std;
int main(){
int N;
scanf("%d", &N);
int dp[50];
memset(dp, 0, sizeof(dp));
dp[1] = 1;
dp[2] = 2;
dp[3] = 4;
for(int i = 4; i <= N; i++){
dp[i] = dp[i - 1] + dp[i - 2] + dp[i - 3];
}
printf("%d", dp[N]);
return 0;
}
P522. 极值问题
//nn - nm - mm = 1
//mm + mn - nn = 1
//(n + m)(n + m) - (n + m)m - mm = 1 => nn + nm -mm = 1
//即解(n, m) 可以推导出 新解(n, m + n)
#include<bits/stdc++.h>
int main (void){
int k;
scanf("%d", &k);
int dp[100000];
memset(dp, 0, sizeof(dp));
dp[0] = 1;
dp[1] = 1;
int x = 0;
for(int i = 2; i < 100000; i++){
dp[i] = dp[i - 1] + dp[i - 2];
if(dp[i] > k){
x = i;
break;
}
}
printf("m=%d\n", dp[x - 2]);
printf("n=%d\n", dp[x - 1]);
return 0;
}
章节 3. 递归算法
P529. 斐波那切数列
#include <bits/stdc++.h>
using namespace std;
int main(){
int N;
scanf("%d", &N);
int dp[50];
memset(dp, 0, sizeof(dp));
dp[1] = 0;
dp[2] = 1;
for(int i = 3; i <= N; i++){
dp[i] = dp[i - 1] + dp[i - 2];
}
printf("%d", dp[N]);
return 0;
}
P530. 倒序数
#include<bits/stdc++.h>
void re(int num){
if (num == 0){
return;
}
printf("%d", num % 10);
num /= 10;
re(num);
}
int main(){
int n;
scanf("%d", &n);
if(n == 0){
printf("%d", n);
return 0;
}
re(n);
return 0;
}
P533. 求最大公约数
#include <bits/stdc++.h>
using namespace std;
int main(){
int n, m;
scanf("%d %d", &n, &m);
printf("gcd=%d", __gcd(n, m));
return 0;
}
P535. 求和
#include <bits/stdc++.h>
using namespace std;
int f(int x){
if(x == 1) return 1;
return f(x - 1) + x;
}
int main(){
int n;
scanf("%d", &n);
printf("%d", f(n));
return 0;
}
P540. 全排列
#include <bits/stdc++.h>
using namespace std;
string s;
string path;
vector<bool> b_path;
void backtrack(){
if(path.size() == s.length()){
cout << path << endl;
return;
}
for(int i = 0; i < s.length(); i++){
if(b_path[i] == true) continue;
b_path[i] = true;
path.push_back(s[i]);
backtrack();
path.pop_back();
b_path[i] = false;
}
}
int main(){
cin >> s;
b_path.resize(s.length());
for(int i = 0; i < s.length(); i++){
b_path[i] = false;
}
backtrack();
return 0;
}
P541. 背包问题
#include <bits/stdc++.h>
using namespace std;
//物品
struct goods{
int no; //物品编号
int w; //物品重量
};
class Solution {
public:
vector<goods> path;
Solution(vector<goods> w, int s){
this->w = w;
this->s = s;
this->b = new bool[w.size()];
for(int i = 0; i < w.size(); i++){
this->b[i] = 0;
}
}
bool exec(){
return backtrack(0);
}
private:
vector<goods> w;
int s;
bool* b;
//DFS搜索,组合,回溯算法
bool backtrack(int x){
int tmps = 0;
//物品和
for(int i = 0; i < path.size(); i++){
tmps = tmps + path[i].w;
}
if(tmps > s){
return false;
}
//物品总重量和背包容量一致
if(tmps == s){
return true;
}
//回溯
for(int i = x; i < w.size(); i++){
if(b[i] == 1) continue;
b[i] = 1;
path.push_back(w[i]);
bool r = backtrack(i + 1);
if(r == true) return true;
path.pop_back();
b[i] = 0;
}
return false;
}
};
int cmp(goods a, goods b){
return a.w > b.w;
}
int main(){
int s, wlen;
vector<goods> w;
//处理输入
scanf("%d%d", &wlen, &s);
for(int i = 0; i < wlen; i++){
goods t;
t.no = i + 1;
scanf("%d", &t.w);
w.push_back(t);
}
//从大到小排序
sort(w.begin(), w.end(), cmp);
//解题和输出结果
Solution so(w, s);
bool r = so.exec();
if(r == false){
printf("not found");
}else{
for(int i = 0; i < so.path.size(); i++){
printf("%d %d\n", so.path[i].no, so.path[i].w);
}
}
return 0;
}