CSP-J模拟卷(二)总结

点我跳转👈🏻

参考答案:

B D C D B

D D B A C

D C D B C

A B B B C

A B B B B

D C B B A

B B D A D

D D D D A

B B C

错题:


第2题

知识点:原码、反码和补码的转换。

原码转反码:除符号位外0变1,1变0。

反码转补码:加1。


第6题

知识点:排列、组合

思路:把ABC看作一个整体,不看D,之后算有D的情况减去即可。

图片

可以算出有3!*6!=4320种方案。

考虑A与D在一起的情况共有四种不同类型

图片

图片

(此处B、C有两种组合,只是没画出来)

可以算出A、D在一起有5!*4=480种方案。

故此题答案为4320-480=3840。选D。


第7题

知识点:排列、组合

思路:从小枚举Y,计算可能的X。

可以得出Y最小是25,则X可以为25

当Y为26时,X则可以为24 25 26。

当Y为27时X则可以为23、24、25、26、27。

可以看出,Y每加1,X则加2可能。Y可以为25~100的任意一个数,X有1~100种可能

Y=48 X的范围:2~48;47

Y=49 X的范围:1~49;49

Y=50 X的范围:1~50。50

从这里可以看出Y=49时,X一次的增长从2变成1了。

故其结果应为1~49和50~100两段的和分开来算,故结果是25*1+25*24*2/2+(50+100)*51/2=4450。


第14题

知识点:c++代码需要通过编译。


第15题

知识点:共2n个数。前两个数比较,大的设为最大值,小的设为最小值,用了一次比较。后面有2*(n-1)个数,大的和最大值比较,小的和最小值比较,做了3*(n-1)次比较,共计3*(n-1)+1=3n-2次比较。


阅读程序第一题

代码:

#include<iostream>
using namespace std;
int count=0, weight[1001], a[7];
int main() {
    for(int i=1;i<=6;i++){
         cin>>a[i];
    }
    for (int x1=0; x1<=a[1]; x1++)
        for (int x2=0; x2<=a[2]; x2++)
            for (int x3=0; x3<=a[3]; x3++)
                for (int x4=0; x4<=a[4]; x4++)
                    for (int x5=0; x5<=a[5]; x5++)
                        for (int x6=0; x6<a[6]+1; x6++)
                        {
                            int w=1*x1+2*x2+5*x3+10*x4+20*x5+50*x6;
                            weight[w]++;
                        }
    for (int i=0; i<=1000; i++)
        if (weight[i]>0) count++;
    cout<<count;
    return 0;
}

这题其实是说有x1个1元币,x2个2元币,x3个5元币,x4个10元币,x5个20元币,x6个50元币,要求有几种组合。


阅读程序第三题

代码:

#include<bits/stdc++.h>
using namespace std;
int n, m, ans, p[101], e[101];
int pow1(int x, int w) {
    int res = 1;
    for (int i = 1; i <= w; i++) {
        res = res * x;
    }
    return res;
}
int main() {
    cin >> n;
    int i = 2;
    while (n != 1) {
        if (n % i == 0) {
            m++;
            p[m] = i;
            e[m] = 0;
            while (n % i == 0) {
                e[m]++;
                n = n / i;
            }
        }
        i++;
    }
    ans = 1;
    for (int i = 1; i <= m; i ++) {
        ans = ans * (p[i] - 1) * pow1(p[i], e[i] - 1);
    }
    cout << ans << endl;
}

这里的代码的功能是分解质因数,每有一个质因数则乘X(X为当前质因数/当前质因数-1)。


完善程序第一题

代码:

#include<bits/stdc++.h>
#define ll long long
using namespace std;
ll n, num, mid, t;
ll a[10000001], b[1000001];
int main() {
    cin >> n;
    for (int i = 1; i <= n; i++) cin >> a[i];
    int i = n;
    while (i > 1) {
        if (a[i]<a[i-1]){
            num++;
            b[num] = a[i];
        }
        else{
            num++;
            b[num] = a[i];
            num++;
            b[num]=a[i-1];
            mid = i - 2;
            break;
        }
        i--;
    }
    if (i == 1) cout<<"No NextPermutation";
    else{
        for (i = 1; i <= num - 1; i++)
            if (b[i]>b[num]){
            t = b[i];
            b[i] = b[num];
            b[num] = t;
            break;
        }
        for (i = 1; i <= mid; i++)cout << a[i] << " ";
        cout << b[num] << " ";
        for (i = 1; i <= num - 1; i++) cout<<b[i]<<" ";
        cout << endl;
    }
}

(这里的代码已补全)

代码是通过这一数列用来推出下一个数列的,其逻辑为一位一位操作以得到B数组。


完善程序第二题

代码:

#include <iostream>
using namespace std;
const int MAXN = 5000;
int n;
struct segment { 
    int a, b;
}A[MAXN];
void sort() // 排序
{
    for (int i = 0; i < n; i++)
        for (int j = i+1; j <= n-1; j++)
            if (A[i].b>A[j].b)
            {
                swap(A[i],A[j]); //交换两个变量
            }
}
int main(){
    cin >> n;
    for (int i = 0; i < n; i++)
        cin >> A[i].a >> A[i].b;
    sort();
    int ans =1, r = A[0].b;
    for (int i = 1; i < n; i++)
    {
        if(A[i].a>=r){
            ans=ans+1;
            r = A[i].b;
        }
    }
    cout << ans << endl;
    return 0;
}

(这里的代码已补全)

这段代码的作用是找出可以选出的最多的区间数(区间不重合),其中运用了二分查找和排序来得到选出的最多的区间数。


THE END