《小题巧练》
努力篇 —— 每天努力一点,离目标更近一点。目录
目录
1.交换值
问题描述:
不允许创建临时变量,交换两个整数的内容。
示例:
输入:12 24
输出:a = 24 b =12
代码实现:
解法1:符合题意,但是有bug。假设a和b都在int类型存储的范围内,但a+b可能超出这个存储范围。
#include <stdio.h> int main() { int a = 0; int b = 0; scanf("%d %d",&a,&b); a = a + b; b = a - b; a = a - b; printf("交换后:a=%d b=%d",a,b); return 0; }
解法2:
注意:要理解按位(二进制位)异或,相同为0,相异为1。
运算规律: a^a=0; b^b=0; a^b^a= b; a^b^b = a;
#include <stdio.h> int main() { int a = 0; int b = 0; scanf("%d %d",&a,&b); a = a ^ b; b = a ^ b;//a^b^b a = b ^ a;//a^a^b printf("交换后:%d %d",a,b); return 0; }
测试结果:
2.一个数二进制序列有几个1
问题描述:
输入一个数据,输出这个数的二进制序列中有多少个1。
示例:
输入:15(00000000 00000000 00000000 00001111)
输出:4
代码实现:
解法1:num%2==1,说明这个二进制序列的最后一位是1。num /= 2;控制循环,也实现了把二进制序列“右移一位”的效果。
#include <stdio.h> int count_one(int num) { int count = 0; while (num>0) { if (num % 2 == 1) { count++; } num /= 2; } return count; } int main() { int num = 0; scanf("%d",&num); int ret = count_one(num); printf("%d的二进制序列中共有%d个1",num,ret); return 0; }
解法2:(n>>i)&1 算数右移,右边抛弃,左边补0;按位与: 一假则假。
00000000 00000000 00000000 00000001
1的二进制序列只有最后1位是1, 按位与“&”上一个数,就可以判断这个数二进制序列最后一位是0还是1
#include <stdio.h> int count_one(int num) { int count = 0; int i = 0; for (i = 0;i<32;i++) { if (((num >> i) & 1) == 1) { count++; } } return count; } int main() { int num = 0; scanf("%d",&num); int ret = count_one(num); printf("%d的二进制序列中共有%d个1", num, ret); return 0; }
解法3:n = n&(n-1);数据的二进制比特位中有几个1,就循环几次。而且如果只循环1次,这个数就是2的n次方。
#include <stdio.h> int count_one(int num) { int count = 0; while (num) { num = num & (num - 1); count++; } return count; } int main() { int num = 0; scanf("%d", &num); int ret = count_one(num); printf("%d的二进制序列中共有%d个1", num, ret); return 0; return 0; }
测试结果:
3.求两个数二进制中不同位的个数
问题描述:
两个int(32位)整数a和b的二进制表达中,有多少个位(bit)不同?
示例:
输入:1 2
输出:2
代码实现:
按位异或,相同为0,相异为1。
#include <stdio.h> int my_count(int a,int b) { int count = 0; int tmp = a ^ b;//tmp的二进制序列有多少个1,就有多少个不同 while (tmp) { tmp = tmp & (tmp-1); count++; } return count; } int main() { int a = 0; int b = 0; scanf("%d %d",&a,&b); int ret = my_count(a,b); printf("%d",ret); return 0; }
测试结果:
4. 获取一个整数二进制序列中所有的偶数位和奇数位
问题描述:
输出一个整数,分别打印出奇数和偶数的二进制序列
示例:
输入:1
输出:奇数: 00000000 00000000
偶数: 00000000 00000001
代码实现:
偶数的获取从30开始 -= 2,原因:如果从32开始,向右移动32位就把整个序列移除去了。
#include <stdio.h> void my_parit(int num) { int i = 0; //获取奇数数 printf("奇数:"); for (i = 31; i >= 1; i -= 2) { printf("%d ",(num >> i) & 1); } printf("\n偶数:"); //偶数 for (i = 30; i >= 0; i -= 2) { printf("%d ", (num >> i) & 1); } } int main() { int num = 0; scanf("%d", &num); my_parit(num); return 0; }
5.上三角矩阵
问题描述:
上三角矩阵即主对角线以下的元素都为0的矩阵,主对角线为从矩阵的左上角至右下角的连线。如果输入方阵是上三角矩阵输出"YES",否则输出"NO"并换行。
示例:
输入: 输出:YES
3 1 2 3 0 4 5 0 0 6
代码实现:
#include <stdio.h> int main() { int arr[10][10] = { 0 }; int n = 0; scanf("%d",&n); int i = 0; int flag = 1; for (i = 0;i<n;i++) { int j = 0; for (j = 0; j < n; j++) { scanf("%d",&arr[i][j]); //下三角元素 if (i > j) { //判断是否为0 if (arr[i][j] != 0) { //更改标记 flag = 0; } } } } if (0 == flag) { printf("NO"); } else { printf("YES"); } return 0; }
测试结果:
![]()
6.进制转换
问题描述:
输入一个整数,转换成用六进制表示。
示例:
输入:10 输入:120
输出:14 输出:320
代码实现:
解法1:
#include <stdio.h> int main() { int num = 0; int arr[100] = { 0 }; scanf("%d",&num); int i = 0; while (num) { arr[i++] = num % 6; num /= 6; } for (i--;i>=0;i--) { printf("%d",arr[i]); } return 0; }
解法2:(递归)
#include <stdio.h> void print(int n) { if (n > 5) { print(n / 6); } printf("%d", n % 6); } int main() { int num = 0; scanf("%d", &num); print(num); return 0; }
测试结果:
7.查找与删除
问题分析:
有一个整数序列(可能有重复的整数),删除指定的某一个整数,输出删除指定数字之后的序列,序列中未被删除数字的前后位置没有发生改变。
示例:
输入: 7
2 3 3 3 4 5 6
3
输出:2 4 5 6
#include <stdio.h> int main() { int n = 0; int arr[100] = { 0 }; scanf("%d",&n); int i = 0; for (i = 0; i < n; i++) { scanf("%d",&arr[i]); } int del = 0; int j = 0; scanf("%d",&del); for (i = 0;i<n;i++) { if (arr[i] != del) { arr[j++] = arr[i]; } } for (i = 0; i < j; i++) { printf("%d ",arr[i]); } return 0; }