CSP题目收集

原题连接

CSP2020 入门组第一轮第16题

Problem

#include <cstdlib>
#include <iostream>
using namespace std;

char encoder[26] = {'C','S','P',0};
char decoder[26];

string st;

int main()  {
  int k = 0;
  for (int i = 0; i < 26; ++i)
    if (encoder[i] != 0) ++k;
  for (char x ='A'; x <= 'Z'; ++x) {
    bool flag = true;
    for (int i = 0; i < 26; ++i)
      if (encoder[i] ==x) {
        flag = false;
        break;
      }
      if (flag) {
        encoder[k]= x;
        ++k;
      }
  }
  for (int i = 0; i < 26; ++i)
     decoder[encoder[i]- 'A'] = i + 'A';
  cin >> st;
  for (int i = 0; i < st.length( ); ++i)
    st[i] = decoder[st[i] -'A'];
  cout << st;
  return 0;
}
  • 判断题

1) 输入的字符串应当只由大写字母组成,否则在访问数组时可能越界。( )
2) 若输入的字符串不是空串,则输入的字符串与输出的字符串一定不一样。()
3) 将第 12 行的“i < 26”改为“i < 16”,程序运行结果不会改变。( )
4) 将第 26 行的"i < 26”改为“i < 16”,程序运行结果不会改变。( )

  • 单选题

5) 若输出的字符串为“ABCABCABCA”,则下列说法正确的是( )。
(A) 输入的字符串中既有S又有P
(B) 输入的字符串中既有S又有B
(C) 输入的字符串中既有A又有P
(D) 输入的字符串中既有A又有B
6)若输出的字符串为“CSPCSPCSPCSP”,则下列说法正确的是( )。
(A) 输入的字符串中既有P又有K
(B) 输入的字符串中既有J又有R
(C) 输入的字符串中既有J又有K
(D) 输入的字符串中既有P又有R

Solution

模拟题,关键是要读懂代码

其中这段代码是为了得到encoder数组, 对于encoder中的初始字母'C'、'S'、'P'不作处理, k从4开始, 所以执行后得到的encoder数组为

C S P A B D E F G H I J K L M N O Q R T U V W X Y Z;

for (int i = 0; i < 26; ++i)
    if (encoder[i] != 0) ++k;
  for (char x ='A'; x <= 'Z'; ++x) {
    bool flag = true;
    for (int i = 0; i < 26; ++i)
      // 对于encoder中的初始字母'C'、'S'、'P'不作处理
      if (encoder[i] ==x) {
        flag = false;
        break;
      }
      if (flag) {
        encoder[k]= x;
        ++k;
      }
  }

接着,通过下面这段代码,建立对应关系, 由于在encoder数组中第一个字母是'C',所以'C'对应'A'。
整体对应关系如下表:

C S P A B D E F G H I J K L M N O Q R T U V W X Y Z
A B C D E F G H I J K L M N O P Q R S T U V W X Y Z

这样就很简单了,找到了对应关系,这样问题就解决了。

  for (int i = 0; i < 26; ++i)
     decoder[encoder[i]- 'A'] = i + 'A';

答案
第一问中:若输入小写字母,可能会越界,比如输入'z', 'z' - 'A'之间相差大于26,会导致数组越界。
第二问中:根据对应关系,输出结果可能一致,比如输入"XYZ".
第三问中:第12行改为i<16无影响,因为i在3的时候就会推出循环
第四问中:第26行修改,结果会影响,因为对应关系会受影响
第五问中:C对应A, S对应B, P对应C, 所以结果一定有C和P A
第五问中:P对应C,R对应S,N对应P, 所以结果一定有P和R D

CSP2020 入门组第一轮第18题

Problem

#include <algorithm>
#include <iostream>
using namespace std;                     
                                         
int n;                                   
int d[50][2];                            
int ans;                                 
                                        
void dfs(int n, int sum) {               
  if (n == 1) {                            
    ans = max(sum, ans);           
    return;                                   
  }                                        
  for (int i = 1; i < n; ++i) {            
    int a = d[i - 1][0], b = d[i - 1][1];  
    int x = d[i][0], y = d[i][1];            
    d[i - 1][0] = a + x;                     
    d[i - 1][1] = b + y;                     
    for (int j = i; j < n - 1; ++j)            
      d[j][0] = d[j + 1][0], d[j][1] = d[j + 1][1];
    int s = a + x + abs(b - y);              
    dfs(n - 1, sum + s);                    
    for (int j = n - 1; j > i; --j)          
      d[j][0] = d[j - 1][0], d[j][1] = d[j - 1][1];
    d[i - 1][0] = a, d[i - 1][1] = b;        
    d[i][0] = x, d[i][1] = y;                
  }                                        
}                                        
                                       
int main() {                             
  cin >> n;                                
  for (int i = 0; i < n; ++i)              
  cin >> d[i][0];
  for (int i = 0; i < n;++i)
     cin >> d[i][1];
  ans = 0;
  dfs(n, 0);
  cout << ans << endl;
  return 0;
}

•判断题

1) 若输入 n 为 0,此程序可能会死循环或发生运行错误。( )
2) 若输入 n 为 20,接下来的输入全为 0,则输出为 0。( )
3) 输出的数一定不小于输入的 d[i][0] 和 d[i][l] 的任意一个。( )

•单选题

4) 若输入的 n 为 20,接下来的输入是 20 个 9 和 20 个 0,则输出为( )。
A. 1890
B. 1881
C. 1908
D. 1917

5) 若输入的 n 为 30,接下来的输入是 30 个 0 和 30 个 5,则输出为( )。
A. 2000
B. 2010
C. 2030
D. 2020
6) (4分)若输入的 n 为 15,接下来的输入是 15 到 1,以及 15到1,则输出为( )。
A. 2440
B. 2220
C. 2240
D. 2420

Solution

我的想法是通过模拟,看出规律。
假设n = 4,
输入数组为d[i][0] = {1, 2, 3 , 4}, d[i][1] = {4, 3, 2, 1}
那么,
第一轮: a = 1, b = 4, x = 2, y = 3, s = 4, 递归dfs(3, 4);
第二轮: a = 3, b = 7, x = 3, y = 2, s = 11, 递归dfs(2, 4 + 11);
第三轮: a = 6, b = 9, x =4, y = 1, s = 18, 递归dfs(1, 4 + 11 + 18);
由于n = 1, 退出递归 , 最终输出 ans = 4 + 11 + 18 = 33;

通过规律可以看出, 第i次递归a = 数组d[i][0]中前i个数累加, x = 数组d[i][0]中第i + 1个数; b = 数组d[i][1]中前i个数累加,y = 数组d[i][1]中第i + 1个数, s = a + x + abs(b - y);
所以,最终结果ans 只要将每次迭代出来的s 相加即可, 比如 n = 4的时候, ans = 4 + 11 + 18 = 33;

问题一:输入零,不作任何处理, ans = 0, 不会报错 , 错误
问题二:全部输入零, 由于每次s = 0, 所以最终结果ans 也为零, 正确
问题三:输入n = 1时, 输出为0, 错误
问题四: 第一轮,s = 18 , 第二轮 s = 27, ... , 第十九轮 s = 180, 所以最后的值为 (18 + 180) * 19 / 2 = 1881 B
问题五: 第一轮,s = 0, 第二轮 s = 5, 第二十九轮 s = 140, 所以最后的值为 (0 + 140) * 29 / 2 = 2030 C
问题六: 第一轮,s = 15 + 14 + |1 - 2| = 30, ... 每次算累加和,
用代码模拟如下

#include <iostream>
#include <cmath>
using namespace std;
const int N = 20;
int a[N];
int b[N];
int main()
{
    int n;
    cin >> n;
    for (int i = 0; i < n; i ++)
    {
        a[i] = n - i ;
        b[i] = i + 1;
    }
    int res = 0;
    for (int i = 0; i < n - 1; i ++){
        int s = 0;
        for (int j = 0; j <= i ; j ++)
        {
            s += a[j] + a[j + 1] + abs(b[j] - b[j + 1]);
        }
        res += s;
    }
    cout << res << endl;
    return 0;
}

答案是2240

C

posted @   CharlesLC  阅读(599)  评论(0编辑  收藏  举报
编辑推荐:
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
阅读排行:
· winform 绘制太阳,地球,月球 运作规律
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· AI与.NET技术实操系列(五):向量存储与相似性搜索在 .NET 中的实现
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
点击右上角即可分享
微信分享提示