- 闫晟淏 的博客
CSP-J模拟卷(二)总结
- @ 2025-8-5 17:03:53
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