信息学奥赛初赛天天练-55-CSP-J2019完善程序1-位运算左移、右移、布尔变量的值、递归算法

PDF文档公众号回复关键字:20240804

在这里插入图片描述

1 完善程序 (单选题 ,每小题3分,共30分)

1.(矩阵变幻)有一个奇幻的矩阵,在不停的变幻,其变幻方式为:

数字 0 变成矩阵

0 0 
0 1

数字 1 变成矩阵

1 1
1 0

最初该矩阵只有一个元素 0,变幻 n 次后,矩阵会变成什么样?

例如,矩阵最初为:[0];

矩阵变幻 1次后:

0 0 
0 1

矩阵变幻 2 次后:

0 0 0 0
0 1 0 1
0 0 1 1
0 1 1 0

输入一行一个不超过 10 的正整数 n。输出变幻 n 次后的矩阵。

试补全程序。

提示:

<< 表示二进制左移运算符,例如 (11)2 << 2=(1100)2;
^ 表示二进制异或运算符,它将两个参与运算的数中的每个对应的二进制位—进行比较,若两个二进制位相同,则运算结果的对应二进制位为 0 ,反之为 1。

01 #include <cstdio>
02 using namespace std;
03 int n;
04 const int max_size = 1 << 10;
05 
06 int res[max_size][max_size];
07 
08 void recursive(int x, int y, int n, int t) {
09     if (n == 0) {
10         res[x][y] = ①;
11         return;
12     }
13     int step = 1 << (n - 1);
14     recursive(②, n - 1, t);
15     recursive(x, y + step, n - 1, t);
16     recursive(x + step, y, n - 1, t);
17     recursive(③, n - 1, !t);
18 }
19 
20 int main() {
21     scanf("%d", &n);
22     recursive(0, 0, ④);
23     int size =  ⑤;
24     for (int i = 0; i < size; i++) {
25         for (int j = 0; j < size; j++)
26             printf("%d ", res[i][j]);
27         puts(" ");
28     }
29     return 0;
30 }	

1 ①处应填( ) [3分]

A n%2

B 0

C t

D 1

2 ②处应填( ) [3分]

A x-step,y-step

B x,y-step

C x-step,y

D x,y

3 ③处应填( ) [3分]

A x-step,y-step

B x+step,y+step

C x-step,y

D x,y-step

4 ④处应填( ) [3分]

A n-1,n%2

B n,0

C n,n%2

D n-1,0

5 ⑤处应填( ) [3分]

A 1<<(n+1)

B 1<<n

C n+1

D 1<<(n-1)

2 相关知识点

1) 位运算

左移(<<)、右移(>>)

左移

左移1位,所有位都左移,末尾补0

右移

右移1位,所有位都右移,首尾补0

//左移 <<  右移 >>
#include<bits/stdc++.h>
using namespace std;

int main(){
	int a=3;
	/*
	  3 对应二进制 
	  0000 0011 
	  左移1位,所有位都左移,末尾补0
	  0000 0110
	  此时对应二进制转十进制为6 
	*/
	int b=3<<1; 
	cout<<"b的值为:"<<b<<endl;//所以b的值为6 
	int c=8;
	/*
	  8 对应二进制 
	  0000 1000 
	  右移1位,所有位都右移,首尾补0
	  0000 0100
	  此时对应二进制转十进制为4 
	*/
	int d=c>>1;
	cout<<"d的值为:"<<d;//所以d的值为4
	return 0;
}

2) 布尔变量

bool是占一个字节的逻辑值,定义出来的变量只有truefalse两个,分别表示真和假,对应10两个值

#include <iostream>
using namespace std;

int main(){
    bool bl=false;
    cout<<bl<<endl;//输出0 
    bl=true;
    cout<<bl<<endl;//输出1
	bl=0;
	cout<<bl<<endl;//输出0
	bl=5;//赋值大于0的数,则为1 
	cout<<bl<<endl;//输出1 
	bl=-1;//赋值不为0的数,则为1 
	cout<<bl<<endl;
	bl=!bl;//! 通过非运算 对bl值改变 1变0 
	cout<<bl; 
    return 0;
}

3) 递归

递归是一种解决问题的方法,它通过将问题分解为更小的子问题来解决。

一个递归函数会在其定义中直接或间接地调用自身

递归通常包括两个部分:基本情况(Base case)和递归步骤(Recursive step)。

基本情况是指当问题规模变得足够小时,可以直接得到解决方案的情况。

调用1次recursive 函数,会递归调用4次,每次输出recursive的值
考虑最后1次,n=1时,t=1时,分别在对应位置输出0,0,0,1
n=2时,也会有4种情况,每种情况输出4个值
具体可以看下面详细分析
08 void recursive(int x, int y, int n, int t) {
09     if (n == 0) {
10         res[x][y] = t;
11         return;
12     }
13     int step = 1 << (n - 1);
14     recursive(x,y, n - 1, t);
15     recursive(x, y + step, n - 1, t);
16     recursive(x + step, y, n - 1, t);
17     recursive(x+step,y+step, n - 1, !t);
18 }

3 思路分析

大致思路

每次从当前,右边,左下,右下4个方向填数,并且遵循当前,右边,左下填的数相同,右下填的数相反

例如

变换1次

变换2次

变换3次

1 ①处应填( C ) [3分]

A n%2

B 0

C t

D 1

分析

从整体程序看,变换主要时0变1,1变0
从下图和下面程序可知,填的数只有t和!t,而逻辑表达式,只有0和1这2种,所以此处填t
14     recursive(②, n - 1, t);
15     recursive(x, y + step, n - 1, t);
16     recursive(x + step, y, n - 1, t);
17     recursive(③, n - 1, !t);
例如
0 变换时,3个t和1个!t
变换成3个0和1个1
1 变换时,3个t和1个!t
变换成3个1和1个0

2 ②处应填( D ) [3分]

A x-step,y-step

B x,y-step

C x-step,y

D x,y

分析

从变换如下程序和变换图形可知,是把当前数变换成4个数,其位置为当前,右,左下,右下
如下程序已经给出了右和左下
而选项中没有给出右下,只能选当,对应的是前x和y
14     recursive(②, n - 1, t);
15     recursive(x, y + step, n - 1, t);
16     recursive(x + step, y, n - 1, t);
17     recursive(③, n - 1, !t);

3 ③处应填( B ) [3分]

A x-step,y-step

B x+step,y+step

C x-step,y

D x,y-step

分析

从变换如下程序和变换图形可知,是把当前数变换成4个数,其位置为当前,右,左下,右下
如下程序已经给出了右和左下
而当前已经被②使用,所以只剩下右下了,对应x+step,y+step
14     recursive(②, n - 1, t);
15     recursive(x, y + step, n - 1, t);
16     recursive(x + step, y, n - 1, t);
17     recursive(③, n - 1, !t);

4 ④处应填( B ) [3分]

A n-1,n%2

B n,0

C n,n%2

D n-1,0

分析

08 void recursive(int x, int y, int n, int t) {
22     recursive(0, 0, ④);
从上面程序可以看出, ④需要填n和t这2个参数
需要经过n次变换,所以此处填n
第1次变换从0开始,所以t为0

5 ⑤处应填( B ) [3分]

A 1<<(n+1)

B 1<<n

C n+1

D 1<<(n-1)

分析

1次变换生成2行2列 2^1
2次变换生成4行4列 2^2
...
n次变换生成2^n行,2^n列
而 1<<n 对应的值和2^n相同
  • 35
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值