CCF-CSP模拟考笔记

编码注意

在使用DevC++时,为了使用万能开头(#include<bits/stdc++.h>),必须在编译选项中加入-std=c++11

image-20230307101026639

CCF-CSP模拟考笔记

⭐️特别提醒:编写代码时最好将变量以及数组定义等放在main函数外面

参考:richenyunqi/CCF-CSP-and-PAT-solution: CCF CSP和PAT考试题解(使用C++14语法) (github.com)

参考:(98条消息) CCF-CSP历年真题大全附题解(202212已更)_csp真题_Hulake_的博客-CSDN博客

官网模拟题:首页 - 计算机软件能力认证考试系统

第一题

202212-1、现值计算

问题描述

根据题意有两种集散方式,其中根据题中的最后一句话“将所有款项转换为当前价值后”,因此我们需要利用后面的计算第K年的x元的当前价值的x(1+i)kx*(1+i)^{-k}计算公式来求解。(依次将每一年的金额转换为当前价值的金额)

解决代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
#include<bits/stdc++.h>
using namespace std;

const int N=1010;
int n;
double i;
int q[N];
double result;

int main(){
cin >> n >> i;
for(int j=0;j <= n;j++){
cin >> q[j];
result+=q[j]*pow(1+i,-j);
}
printf("%.3f",result)
return 0;
}

//网上100分参考代码
#include<iostream>
#include<cmath>
using namespace std;

const int N = 1010;
int n;
double i;
int q[N];
double all;

int main() {
cin >> n >> i;
for (int j = 0; j <= n; j++) {
cin >> q[j];
all += q[j] * pow(1 + i, -j);
}
printf("%.3f", all);
return 0;
}

202209-1、如此编码

题目描述

m%cj=i=1jci1×bim \% c_j=\sum_{i=1}^j c_{i-1} \times b_i可知有m \% c_3 & =c_0 \times b_1+c_1 \times b_2+c_2 \times b_3 \\,又因为c2=a1a2c_2=a_1*a_2,也就是c2=c1a2c_2=c_1*a_2,则可以得到\frac{m \% c_3}{c_2} & =\frac{c_0 \times b_1+c_1 \times b_2+c_2 \times b_3 \\}{c_2}=\frac{c_0 \times b_1+c_1 \times b_2 \\}{c_2}+b_3,同时显然可以知道c0×b1+c1×b2c2<1\frac{c_0 \times b_1+c_1 \times b_2 \\}{c_2}<1,因此得到以下求bib_i的代码:

1
2
3
4
mul=c*a[i];		//mul就是c[i],c就是c[i-1]
b[i]=int((m%mul)/c);
c=mul;
printf("%d ",b[i]);//输出结果

解决代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
//第一次85分代码如下:
#include<bits/stdc++.h>
using namespace std;

int main() {
int n,m;
cin>>n>>m;
vector<int>a(n+1,0);//下标从1开始
vector<int>c(n,0);//下标从0开始
vector<int>b(n+1,-1);

//输入每道题的选项数目
for(int i=1;i<=n;++i){
cin>>a[i];
}

c[0]=1;
int mul;
for(int i=1;i<=n;++i){
mul=c[i-1]*a[i];
c[i]=mul;
}

int remainder,quotient ;//定义余数和商
for(int i=n-1;i>=0;--i){
remainder=m%c[i];
quotient=m/c[i];
b[i+1]=quotient;
m=remainder;
}
//输出结果
for(int i=1;i<=n;++i){
printf("%d ",b[i]);
}

return 0;
}

//修改后100分的代码:
#include<bits/stdc++.h>
using namespace std;

int main() {
int n,m;
cin>>n>>m;
vector<int>a(n+1,0);//下标从1开始
// vector<int>c(n,0);//下标从0开始
int c=1;
vector<int>b(n+1,-1);

//输入每道题的选项数目
for(int i=1;i<=n;++i){
cin>>a[i];
}

int mul;
for(int i=1;i<=n;++i){
mul=c*a[i];
b[i]=int((m%mul)/c);
c=mul;
printf("%d ",b[i]);//输出结果
}

return 0;
}


//网上100分参考代码:
#include<iostream>
using namespace std;

const int N = 21;
int n, m;
int a[N];
int b[N];
int c = 1, tc = 1;

int main() {
cin >> n >> m;
for (int i = 0; i <n; i++)
cin >> a[i];
for (int i = 0; i <n; i++) {
tc = a[i] * c;
b[i] = int((m % tc) / c);
c = tc;
cout << b[i] << ' ';
}

return 0;
}

202206-1、归一化处理

问题描述

注意最重要的是误差不能超过10410^{-4},其它直接根据公式编写代码即可。

解决代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
#include<bits/stdc++.h>
using namespace std;

//存储整数的数组a要定义为double类型如果定义为int类型会导致最后的输出结果的误差大于了10-4
int n;
vector<double>a(1000,0);
double mean_a;
double D_a;

int main() {
cin>>n;
double mid_sum=0;
for(int i=0;i<n;++i){
cin>>a[i];
mid_sum+=a[i];
}

mean_a=mid_sum/n;

double sum=0;
for(int j=0;j<n;++j){
sum+=pow(a[j]-mean_a,2);
}
D_a=sqrt(sum/n);

double f;
for(int k=0;k<n;++k){
f=(a[k]-mean_a)/(D_a);
printf("%f\n",f);
}
return 0;
}

202203-1、未初始化警告

问题描述

这道题需要注意的是如果输入右值为0的话,则表示的是右值为常数;主要利用map进行hash映射来判断。

PS:map只能初始化大小,不能初始化值

解决代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
#include<bits/stdc++.h> 
using namespace std;


int main() {
int n,k;
cin>>n>>k;
int key,key1,counts=0;
unordered_map<int,int>hash(n);
cin>>key>>key1;
if(key1==0)
hash[key1]=1;
else{
hash[key1]=-1; //未初始化
counts++;
}
hash[key]=1; //已初始化
for(int i=1;i<k;++i){
cin>>key>>key1;
if(key1==0||hash[key1]==1){//已初始化
hash[key1]=1;
}else{//未初始化
hash[key1]=-1;
counts++;
}
hash[key]=1;
}
printf("%d",counts);
return 0;
}

202112-1、序列查询

问题描述

采用 lower_bound()查找位置下标,如果A集合中存在与N相等的元素,则直接返回的是与N相等的元素的位置下标;如果A集合中不存在与N相等的元素,则返回的是第一个大于N的元素的位置下标,因此需要根据题意将位置下标-1。

lower_bound() 函数用于在指定区域内查找不小于目标值的第一个元素。

解决代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#include<bits/stdc++.h>
using namespace std;


int main() {
int n,N;
cin>>n>>N;
vector<int>A(n+1,0);
for(int i=1;i<=n;++i){
cin>>A[i];
}
int sum=0,f;
N=N-1;
while(N>=0){
f=lower_bound(A.begin(),A.end(),N)-A.begin();//lower_bound返回一个迭代器
if(A[f]!=N)f=f-1; //注意如果A[f]的值等于N的值则返回的f不减1
sum+=f;
N=N-1;
}
printf("%d",sum);
return 0;
}

202109-1、数组推导

问题描述

重点是B数组的单调不降性。同时求最小和时连续出现多个相等元素时最小和加上0。

解决代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#include<bits/stdc++.h>
using namespace std;

int main() {
int n,min_sum=0,max_sum=0;
cin>>n;
int max_val,tmp;
cin>>tmp;//输入数据为不递减
max_val=tmp;
min_sum+=tmp;
max_sum+=tmp;
for(int i=1;i<n;++i){//从第二个输入整数开始
cin>>tmp;
max_sum+=tmp;//最大和就是输入序列直接求和
if(tmp!=max_val){//最大值发生变化
max_val=tmp;
min_sum+=tmp; //当连续出现多个相等元素时,B中可以存在多个0的情况,因此最小和加上0
}
}
printf("%d\n",max_sum);
printf("%d",min_sum);
return 0;
}

202104-1、灰度直方图

问题描述

灰度值只能是[0,L)内的整数,本题要求相同灰度值的像素个数,因此可以采用unordered_map求解。

解决代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#include<bits/stdc++.h>
using namespace std;

int main() {
int n,m,L;
cin>>n>>m>>L;
unordered_map<int,int>hash(L);
int M_A;
for(int i=0;i<n*m;++i){
cin>>M_A;
++hash[M_A];
}
for(int i=0;i<L;++i){
cout<<hash[i]<<" ";
}
return 0;
}

202012-1、期末预测之安全指数

题目描述

这道题很简单!求和,比较即可。

解决代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
#include<bits/stdc++.h>
using namespace std;


int main() {
int n,w,score,x=0;
cin>>n;
for(int i=0;i<n;++i){
cin>>w>>score;
x+=w*score;
}
cout<<max(0,x);
return 0;
}

202009-1、称检测点查询

问题描述

参考:(99条消息) CCF-CSP C/C++ 202009-1 称检测点查询 题解_语句应用题设核酸检测数据库中有下面三个采样点(编号,名称,所属街道,类型,地_DonquixoteXXXXX的博客-CSDN博客

关键:灵活运用sort方法的cmp自定义排序规则。

解决代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
#include<bits/stdc++.h>
using namespace std;

//自定义排序规则——升序排序
bool cmp(pair<int,int>&a,pair<int,int>&b){
if(a.first==b.first)return a.second<b.second;
return a.first<b.first; //如果a.first<b.first为true,则表明符合我们的排序规则,不进行位置交换;否则需要进行a,b的位置交换。
}

int main() {
int n,X,Y;
cin>>n>>X>>Y;
pair<int,int>local[n+1];
int x,y;
double D;
for(int i=1;i<=n;++i){
cin>>x>>y;
D=(pow(X-x,2)+pow(Y-y,2));
local[i]=make_pair<>(D,i);
// cout<<local[i].first<<" ";
// cout<<endl;
}
//排序
sort(local+1,local+n+1,cmp);//sort对pair排序会默认对pair的first进行排序
for(int i=1;i<=3;++i){
cout<<local[i].second<<endl;
}
return 0;
}

202006-1、线性分类器

问题描述

分析:

  1. 判断点在线的哪一侧可以通过将点坐标代入线表达式:θ1x+θ1y+θ0=0\theta_{1}x+\theta_{1}y+\theta_{0}=0中。
  2. 使得θ1x+θ1y+θ0>0\theta_{1}x+\theta_{1}y+\theta_{0}>0为一个类别,使得θ1x+θ1y+θ0<0\theta_{1}x+\theta_{1}y+\theta_{0}<0为另一个类别。
  3. 最好采用结构体来存储点的三维数据。

输入:

1
2
3
4
5
6
7
8
9
10
11
12
13
9 3
1 1 A
1 0 A
1 -1 A
2 2 B
2 3 B
0 1 A
3 1 B
1 3 B
2 0 A
0 2 -3
-3 0 2
-3 1 1

解决代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
//第一次尝试始终不通过的代码:——原因未知(示例数据可通过)
#include<bits/stdc++.h>
using namespace std;

const int N=1001,M=21;
int array_2[N][2];
string array_3[N];
vector<string>ans(M,"Yes");//初始化全为Yes

int main() {
int n,m;
cin>>n>>m;
// int array_2[n][2];
// string array_3[n];
int other_index=0;
bool flag=false;
for(int i=0;i<n;++i){
for(int j=0;j<2;++j){
cin>>array_2[i][j];
}
cin>>array_3[i];
//记录下与第一个点不同类型的第一个点的坐标
if(!flag&&array_3[i]!=array_3[0]){//取另一个类型的第一个点
other_index=i;
flag=true;
}
// cout<<"type"<<array_3[i]<<" ";
}
// cout<<"other_index:"<<other_index;
// vector<string>ans(m,"Yes");//初始化全为Yes
int theta0,theta1,theta2,pre,cur,flag1,flag2;
for(int i=0;i<m;++i){
cin>>theta0>>theta1>>theta2;
for(int j=0;j<n;++j){
cur=theta1*array_2[j][0]+theta2*array_2[j][1]+theta0;
// pre=theta1*array_2[j-1][0]+theta2*array_2[j-1][1]+theta0;
flag1=theta1*array_2[0][0]+theta2*array_2[0][1]+theta0;//用第一个点的类型以及位于线的位置方向来作为一个标准
flag2=theta1*array_2[other_index][0]+theta2*array_2[other_index][1]+theta0;//另一个类型
if(flag1*flag2>0||(cur*flag1>0&&array_3[j]!=array_3[0])||(cur*flag2>0&&array_3[j]!=array_3[other_index])){//如果同方向但是不同类型则这条线不能达到划分目的
ans[i]="No";
break;
}
}
}
for(int i=0;i<m;++i){
cout<<ans[i]<<endl;
}
return 0;
}

//重写后100分代码:
#include<bits/stdc++.h>
using namespace std;

const int N=10001,M=21;
struct points{
int x,y;
int fvalue;
char type;
}pt[N];

struct line{
int c0,c1,c2;
}li[M];

int main() {
int n,m;
cin>>n>>m;
//输入数据
for(int i=0;i<n;++i){
cin>>pt[i].x>>pt[i].y>>pt[i].type;
}
for(int i=0;i<m;++i){
cin>>li[i].c0>>li[i].c1>>li[i].c2;
}
for(int j=0;j<m;++j){
char ch1,ch2;
int flag=1;
//以第一个点来设定标准
pt[0].fvalue=pt[0].x*li[j].c1+pt[0].y*li[j].c2+li[j].c0;
if(pt[0].fvalue>0&&pt[0].type=='A'||pt[0].fvalue<0&&pt[0].type=='B'){//始终保证ch1在>0的方向
ch1='A';
ch2='B';
}
if(pt[0].fvalue>0&&pt[0].type=='B'||pt[0].fvalue<0&&pt[0].type=='A'){
ch1='B';
ch2='A';
}
for(int i=1;i<n;++i){//遍历i个点
pt[i].fvalue=pt[i].x*li[j].c1+pt[i].y*li[j].c2+li[j].c0;
if(pt[i].fvalue>0&&pt[i].type!=ch1){
flag=0;
cout<<"No"<<endl;
break;
}
if(pt[i].fvalue<0&&pt[i].type!=ch2){
flag=0;
cout<<"No"<<endl;
break;
}
}
if(flag){
cout<<"Yes"<<endl;
}
}
return 0;
}

//网上100分参考代码:
#include<bits/stdc++.h>
using namespace std;
struct point{ //点结构体
int x,y;
int sum; //计算点带入直线里的值
char type;
};
point pt[1010];
struct line{ //直线结构体
int c0,c1,c2;
};
line ln[110];
int main(){
int n,m;
cin >> n >> m;
int i,j;
for(i = 0;i < n;i++){
cin >> pt[i].x >> pt[i].y >> pt[i].type;
}
for(i = 0;i < m;i++){
cin >> ln[i].c0 >> ln[i].c1 >> ln[i].c2;
}
for(i = 0;i < m;i++){
char ch1,ch2;
int flag = 1;
pt[0].sum = ln[i].c0 + pt[0].x*ln[i].c1 + pt[0].y*ln[i].c2; //以第一个点作为标准
if((pt[0].sum>0 && pt[0].type=='A') || (pt[0].sum<0 && pt[0].type=='B')){ //在直线上方的点的type值设置为ch1
ch1 = 'A';
ch2 = 'B';
}
if((pt[0].sum>0 && pt[0].type=='B') || (pt[0].sum<0 && pt[0].type=='A')){ //在直线上方的点的type值设置为ch1
ch1 = 'B';
ch2 = 'A';
}
for(j = 1;j < n;j++){
pt[j].sum = ln[i].c0 + pt[j].x*ln[i].c1 + pt[j].y*ln[i].c2;
if(pt[j].sum>0 && pt[j].type==ch2){ //如果直线上的点的type值为ch2,说明不能准确分类
flag = 0;
cout << "No" <<endl;
break;
}
if(pt[j].sum<0 && pt[j].type==ch1){ //如果直线下的点的type值为ch1,说明不能准确分类
flag = 0;
cout << "No" <<endl;
break;
}
}
if(flag) //flag始终为1,说明准确进行了分类
cout << "Yes" <<endl;
}
}
  • Copyright: Copyright is owned by the author. For commercial reprints, please contact the author for authorization. For non-commercial reprints, please indicate the source.
  • Copyrights © 2023-2024 Guijie Wang
  • Visitors: | Views:

请我喝杯咖啡吧~

支付宝
微信