#4463. 普及组 CSP-J 第10套初赛模拟试题

普及组 CSP-J 第10套初赛模拟试题

一.单项选择题

共15题,每题2分,共30分;每题有且仅有一个正确选项。

  1. 在C++中使用cin和cout应该调用( )库。 {{ select(1) }}
  • iostream
  • cstdio
  • cmath
  • stack
  1. n是一个三位数,那n的十位数为( )。 {{ select(2) }}
  • ( n%10)/10
  • ( n/100)%10
  • ( n/100)%100
  • ( n%100)/10
  1. 已知大写字母 A 的ASCII编码为65(十进制),则大写字母 J 的十进制ASCII编码为( )。

{{ select(3) }}

  • 71
  • 72
  • 73
  • 74
  1. 计算机用户可以根据需要安装软件,那么计算机的软件系统一般分为( )。

{{ select(4) }}

  • 系统软件和应用软件
  • 管理软件和控制软件
  • 军用软件和民用软件
  • 高级软件和一般软件
  1. 一片容量为8GB的SD卡能存储大约( )张大小为2MB的数码照片。

{{ select(5) }}

  • 1600
  • 2000
  • 4000
  • 16000
  1. 一个字节(byte)由( )个二进制位组成。( )

{{ select(6) }}

  • 8
  • 16
  • 32
  • 以上皆有可能
  1. 前缀表达式“+3*2+5 12”的值是( )。 {{ select(7) }}
  • 23
  • 25
  • 37
  • 65
  1. 一个字长为8位的整数的补码是1111 1001,则它的原码是( )。

{{ select(8) }}

  • 0000 0111
  • 0111 1001
  • 1111 1001
  • 1000 0111
  1. 基于比较的排序时间复杂度的下限是( ),其中n表示待排序的元素个数。

{{ select(9) }}

  • O(n)
  • O(nlogn)
  • O(logn)
  • O(n2n^2)
  1. 一棵二叉树的前序遍历序列是ABCDEFG,后序遍历序列是CBFEGDA。则根结点的左子树的结点个数可能是( )。 {{ select(10) }}
  • 2
  • 3
  • 4
  • 5
  1. 十进制小数13.375对应的二进制数是( )。 {{ select(11) }}
  • 1101.011
  • 1011.011
  • 1101.101
  • 1010.01
  1. 根据域名代码规定,表示政府部门网站的域名代码是( )。 {{ select(12) }}
  • .net
  • .gov
  • .com
  • .org
  1. 计算机中的数值信息分为整数和实数(浮点数)。实数之所以能够表示很大或者很小的数,是由于使用了( )。

{{ select(13) }}

  • 阶码
  • 补码
  • 反码
  • 较长的尾数
  1. 计划展出10幅不同的画,其中1幅水彩画、4幅油画、5幅国画,排成一行陈列,要求同一品种的画必须连在一起,并且水彩画不放在两端,那么不同的陈列方式有( )种。 {{ select(14) }}
  • 2880
  • 17280
  • 8640
  • 5760
  1. 定义一种字符串操作,一次可以将其中一个元素移到任意位置。举例说明,对于字符串“BCA”可以将“A”移到“B”之前,变字符串“ABC”。如果要将字符串“DACHEBCIF”变成“ABCDEFGHI”最少需要( )次操作。 {{ select(15) }}
  • 4
  • 5
  • 6
  • 7

二、阅读程序

程序输入不超过数组或字符串定义的范围;除特殊说明外,判断题1.5分,选择题4分,共计40分

(1)

#include<bits/stdc++.h> 
using namespace std;
const int maxn =50;
void getnext(char str[]){
	int 1= strlen(str),i,j,k, temp;
	k = 1 - 2;
    while(k- 1>=0 && str[k] > str[k+ 1]) k --;
    i = k + 1;
    while(i < 1&& str[i]> str[k]) i++;
     temp  = str[k];
       str[k] =  str[i - 1];
     str[i- 1] = temp;
      for( i = 1 - 1;i > k;i --)
      for(j = k + 1 ;j < i;j ++)
      if( str[j] > str[j + 1]) {
         temp  = str[j];
         str[j] = str[j + 1];
         str[j+ 1] = temp;
       }
     return ;
   }
    int main(){
    char a[maxn];
    int  n;
    cin>>a>> n;
    while(n>0){
     getnext(a);
      n--;
    }
   cout<<a<<endl;
    return 0;
  }
  1. (1分)若输入的字符串a是升序的,那么无论n为多少,第13行的循环都不会执行(执行的条件不满足)。( ) {{ select(16) }}
  • 正确
  • 错误

17.若输入的n等于2,对于第27行,第一次执行完和第二次执行完的字符串最多只有2个字符位置不同。( ) {{ select(17) }}

  • 正确
  • 错误
  1. 程序执行完第7行时,第k+1个字符到第l-1个字符的值是不严格递减的。( ) {{ select(18) }}
  • 正确
  • 错误
  1. 程序执行完第12行时,第k+1个字符到第l-1个字符的值是不严格递减的。( ) {{ select(19) }}
  • 正确
  • 错误
  1. 若输入的字符串有x个字符并且是严格降序的,输入的n等于1,则第16~18行会执行( )次。 {{ select(20) }}
  • (x-1)(x-2)/2
  • x(x-1)/2
  • x(x+1)/2
  • 0
  1. 若输入的字符串有x个字符并且都相同,输入的n等于1,则第16~18行会执行( )次。 {{ select(21) }}
  • (x-1)(x-2)/2
  • x(x-1)/2
  • x(x+1)/2
  • 0

(2)

  #include
  using namespace std;
  int  w[35000],d[35000], dp[35000];
  int main()
  {
      int n,m;
       scanf("%d%d",&n,&m);
     for(int  i=1;i<=n;++i)
        scanf("%d%d",&w[i],&d[i]);
     for(int  i=1;i<=n;++i)
     {
           for(int  j=m;j>=w[i];--j)
             dp[j]=max(dp[j], dp[j-w[i]]+d[i]) ;
     }
     printf("%d", dp[m]);
     return 0;
 }

  1. (1分)上述代码中,双重循环里循环变量j的枚举顺序改为从w[i]到m,输出结果一定不变。( ) {{ select(22) }}
  • 正确
  • 错误
  1. 上述代码中,双重循环中变量i的枚举顺序改为从n到1,输出结果一定不变。() {{ select(23) }}
  • 正确
  • 错误

24.若输入数据中,1<=n<=30000,1<=m<=30000,1<=w[i]<=30000,1<=d[i]<=30000,则所求答案一定没有溢出。( ) {{ select(24) }}

  • 正确
  • 错误
  1. 若输入数据中,1<=n<=30000,1<=m<=30000,1<=w[i]<=30000,1<=d[i]<=10⁹,则所求答案一定没有溢出。( ) {{ select(25) }}
  • 正确
  • 错误
  1. 当输入为:
4 6
1 4
2 6
3 12
2 7

输出为( )。 {{ select(26) }}

  • 17
  • 28
  • 29
  • 23
  1. 上述代码的时间复杂度为( )。 {{ select(27) }}
  • O(n)
  • O(n2n^2m)
  • O(nm)
  • O(nm2m^2)

(3)

 #include<iostream>
  using namespace std;
  const int NUM =5;
    int  r(int  n) {
         int i;
        if(n<=NUM) return n;
         for(int  i= 1;i <= NUM;++i)
           if(r(n - i) < 0) return  i;
       return   - 1 ;
  }
   int  main() {
    int  n;
    cin>>n;
    cout<<r(n)<<endl;
    return 0;
  }
  1. 将第7行“i=1”改为“i=0”,程序不会出错。( ) {{ select(28) }}
  • 正确
  • 错误
  1. 程序输出的结果有可能小于-1。( ) {{ select(29) }}
  • 正确
  • 错误
  1. 若程序两次输入的值分别为n1n_1n2n_2,且有n1n_1-n2n_2=1的关系,则对于这两次运行的结果ans1ans_1ans2ans_2,有ans1ans_1-ans2ans_2=1。( ) {{ select(30) }}
  • 正确
  • 错误
  1. 若输入的n大于等于6时,程序一定至少执行一次第9行。( ) {{ select(31) }}
  • 正确
  • 错误
  1. (2分)若输入2020,输出的结果为( )。 {{ select(32) }}
  • 3
  • 4
  • 5
  • -1
  1. 若已知0<=n<=100,则要使输出的结果为-1,则n的取值有( )种。 {{ select(33) }}
  • 10
  • 12
  • 14
  • 16

三、完善程序

单选题,除特殊说明外,每小题3分,共计30分。

  • (1)(过河问题) 在一个月黑风高的夜晚,有一群人在河的右岸,想通过唯一的一根独木桥走到河的左岸。在伸手不见五指的黑夜里,过桥时必须借照灯光来照明,不幸的是,他们只有一盏灯。另外,独木桥上最多能承受两个人同时经过,否则将会坍塌。每个人单独过独木桥都需要一定的时间,不同的人用的时间可能不同。两个人一起过独木桥时,由于只有一盏灯,所以需要的时间是较慢的那个人单独过桥所花费的时间。现在输入N(2<=N<1000)和这N个人单独过桥需要的时间,请计算总共最少需要多少时间,他们才能全部到达河左岸。 例如,有3个人甲、乙、丙,他们单独过桥的时间分别为1、2、4,则总共最少需要的时间为7。具体方法是:甲、乙一起过桥到河的左岸,甲单独回到河的右岸将灯带回,然后甲、丙在一起过桥到河的左岸,总时间为2+1+4=7。
#include<iostream>
#include<cstring>
using namespace std;
const  int SIZE=100;
const  int  INFINITY = 10000;
const bool LEFT=true;
const bool RIGHT=false;
const bool LEFT_TO_RIGHT= true;
const bool RIGHT_TO_LEFT= false;
   int  n, hour[SIZE];
   bool  pos[SIZE];
 int max(int a, int b)
   {
      if(a>b)
         return a;
     else
        return b;
   }
 int go(bool stage)
  {
      int i,j, num, tmp, ans;
      if( stage==RIGHT_TO_LEFT)
     {
        num  = 0;
        ans = 0;
        for( i = 1;i < = n;++ i)
           if(pos[i] == RIGHT)
            {
            num  ++;
            if(hour[i]> ans)
                ans= hour[i];
            }
        if(①   )
          return ans;
        ans=INFINITY;
         for( i = 1;i< = n - 1;++ i)
            if(pos[i] == RIGHT)
              for(j = i + 1;j< = n;++j)                                                                      
              if(pos[j] = = RIGHT)
				{
                  pos[i] = LEFT;
                  pos[j] = LEFT;
                   tmp= max( hour[i], hour[j])+_②_;
                   if(tmp
                    ans=tmp;
                   pos[i] = RIGHT;
                  pos[j] = RIGHT;
               }
        return ans;
       }
       if(stage == LEFT_TO_RIGHT)
     {
        ans=INFINITY;
        for( i = 1;i < = n;++ i)
           if( ③ )
            {
            pos[i] = RIGHT;
             tmp=_④_;
            if(tmp
              ans =tmp;
                 ⑤   ;
           }
        return ans;
     }
      return 0;
}
 int main()                                   
  {
    int i;
      cin>>n;
    for( i = 1;i < = n;+ + i)
      {
        cin>>hour[i];
        pos[i] = RIGHT;
      }
      cout<< go(RIGHT_TO_LEFT)<< endl;
      return 0;
}
  1. ①处应填() {{ select(34) }}
  • num<=0
  • num<=1
  • num<=2
  • num<=3
  1. ②处应填() {{ select(35) }}
  • go(RIGHT)
  • go(!pos[i])
  • go(LEFT_TO_RIGHT)
  • go(RIGHT_TO_LEFT)
  1. ③处应填() {{ select(36) }}
  • pos[i]=LEFT
  • pos[i]==RIGHT
  • num<=2
  • num<=3
  1. ④处应填() {{ select(37) }}
  • hour[i]+ go(LEFT_TO_RIGHT)
  • hour[i]+ go(RIGHT_TO_LEFT)
  • go(LEFT_TO_RIGHT)
  • go(RIGHT_TO_LEFT)
  1. ⑤处应填() {{ select(38) }}
  • return ans
  • tmp=0
  • pos[i]=RIGHT
  • pos[i]=LEFT

(2)(国王放置) 在n×m的棋盘上放置k个国王要求k个国王互相不攻击,有多少种不同的放置方法?假设国王放置在第(x,y)格,国王的攻击区域是(x-1,y-1),(x-1,y),(x-1,y+1),(x,y-1),(x,y+1),(x+1,y-1),(x+1,y),(x+1,y+1)。读入三个数n,m,k,输出答案。题目利用回溯法求解。棋盘行标号为0~n-1,列标号为0~m-1。 试补全程序。

#include<cstdio>
#include<cstring>
  int  n,m,k, ans;
  int  hash[5][5];
 void work(int x, int y, int tot){
     int  i,j;
    if(tot == k){
         ans ++;
         return;
   }
    do  {
      while(hash[x][y]){
         y ++ ;
          if(y = = m) {
            x ++;
           y=   ①   ;
        }
          if( x == n)
          return;
      }
      for( i = x - 1;i <= x + 1;i ++)
          if ( i>= 0 && i < n)
           for(j= y - 1;j <= y + 1;j ++)                                                                        
            if(j >= 0 && j < m)
             ②   ;
             ③   ;
        for( i = x - 1;i <= x + 1;i ++)
         if( i>= 0&& i < n)
           for (j= y - 1;j <= y + 1;j ++)
            if(j >= 0&&j< m)
              hash[i][j] - - ;
         ④ ;
        if(y = = m) {
          x ++;
          y = 0;
        }
        if ( x = =  n)
         return;
     } while(1);
  }
   int  main() {
  scanf("%d%d%d",&n,&m,&k);
   ans = 0;
  memset(hash,0, sizeof(hash));
   ⑤   ;
   printf("%d", ans);
  return 0;
  }
  1. ①处应填() {{ select(39) }}
  • 0
  • 1
  • x
  • x+1
  1. ②处应填( ) {{ select(40) }}
  • hash[i][j]=1
  • hash[i][j]++
  • hash[i][j]=0
  • hash[i][j]--
  1. ③处应填( ) {{ select(41) }}
  • work(x,y+1,tot+1)
  • y--
  • y++
  • work(x,y,tot+1)
  1. ④处应填( ) {{ select(42) }}
  • y=0
  • y=1
  • y--
  • y++
  1. ⑤处应填( ) {{ select(43) }}
  • work(n-1,m-1,0)
  • work(n,m,0)
  • work(0,0,0)
  • work(1,1,0)