(沐枫)电子学会三级考试练习题

考试范围

电子学会三级考试习题网址

三级标准:

  1. 掌握算法以及算法性能、算法效率的概念;
  2. 掌握基本算法中枚举的概念;
  3. 掌握基本算法中递归的概念;
  4. 掌握自调用函数的应用,实现基本算法中的递归方法;
  5. 掌握基本算法中由递归变递推的方法。 能够使用上述方法编写指定功能的正确完整的程序。

章节 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;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值