6.1 进制转换
二进制数(十转二)
习题描述
大家都知道,数据在计算机里中存储是以二进制的形式存储的。 有一天,小明学了C语言之后,他想知道一个类型为unsigned int 类型的数字,存储在计算机中的二进制串是什么样子的。 你能帮帮小明吗?并且,小明不想要二进制串中前面的没有意义的0串,即要去掉前导0。
输入描述:多行,每一行表示要求的数字
输出描述:输出共T行。每行输出求得的二进制串
代码表示:
#include <bits/stdc++.h>
using namespace std;
int main() {
unsigned int n;
while (scanf("%u", &n) != EOF) {
vector<int>binary; // 使用vector<bool>来存储二进制位
while (n != 0) {
binary.push_back(n % 2);
n /= 2; //取走余数之后剩下的
}
for (int i = binary.size()-1; i>=0; --i)//逆着读出
{
printf("%d", binary[i]);
}
printf("\n");
}
return 0;
}
进制转换(限制范围)
题目描述:
代码表示:
#include <bits/stdc++.h>
using namespace std;
string Divide(string str, int x) { // 自定义字符串除法函数
int remainder = 0; // 保存余数
for (int i = 0; i < str.size(); ++i) {
int current = remainder * 10 + str[i] - '0';
str[i] = current / x + '0'; // 更新商的字符表示
remainder = current % x; // 更新余数
}
int pos = 0;
while (str[pos] == '0') { // 寻找首个非 0 下标
pos++;
}
return str.substr(pos); // 删除前置多余的 0
}
int main() {
string str;
while (cin >> str) {
vector<int> binary; // 存储二进制位
while (str.size() != 0) {
int last = str[str.size() - 1] - '0'; // 获取最低位的值
binary.push_back(last % 2); // 将最低位对2取模,得到二进制位
str = Divide(str, 2); // 将当前数值整除以2
}
for (int i = binary.size() - 1; i >= 0; --i) { // 逆序输出二进制位
printf("%d", binary[i]);
}
printf("\n");
}
return 0;
}
6.2 最大公约数与最小公倍数
最大公约数(哈工大)
题目描述:
代码表示:
#include <bits/stdc++.h>
using namespace std;
int GCD(int a, int b) {
if (b == 0) {
return a;
} else {
return GCD(b, a % b);
}
}
int main() {
int a, b;
while (scanf("%d%d", &a, &b) != EOF) {
printf("%d\n", GCD(a, b));
}
return 0;
}
心得体会:
举例说明这个GCD(a,b)是什么意思
假设我们要计算 48 和 18 的最大公约数(GCD)。
- 因为 b(18)不等于 0,所以我们继续调用 GCD(18, 48 % 18)。
- 计算 48 除以 18 的余数,得到 12。现在我们将调用 GCD(18, 12)。
- 因为 b(12)不等于 0,所以我们再次调用 GCD(12, 18 % 12)。
- 计算 18 除以 12 的余数,得到 6。现在我们将调用 GCD(12, 6)。
- 因为 b(6)不等于 0,所以我们再次调用 GCD(6, 12 % 6)。
- 计算 12 除以 6 的余数,得到 0。现在我们将调用 GCD(6, 0)。
- 因为此时 b(0)等于 0,根据代码中的逻辑,返回 a(6)作为最大公约数。
因此,最终得到 48 和 18 的最大公约数是 6。
最小公倍数
题目描述:
代码表示:
#include <bits/stdc++.h>
using namespace std;
int GCD(int a, int b) {
if (b == 0) {
return a;
} else {
return GCD(b, a % b);
}
}
int main() {
int a, b;
// 循环读取输入的两个整数,并计算它们的最大公约数
while (scanf("%d%d", &a, &b) != EOF) {
// 输出 a 和 b 的乘积除以它们的最大公约数
printf("%d\n", a * b / GCD(a, b));
}
return 0;
}
心得体会:我滴天!这就是最小公倍数 a * b / GCD(a, b)
6.3 质数
质数也称素数,是指只能被其自身和 1 整除的正整数。
素数判定(哈工大复试)
题目描述:
yes
代码表示:
#include <bits/stdc++.h>
using namespace std;
bool Judge(int x) { // 判断是否为质数
if (x < 2) { // 小于 2 必定不是质数
return false;
}
int bound = sqrt(x); // 确定判断上界
for (int i = 2; i <= bound; ++i) {
if (x % i == 0) {
return false; // 如果能被整除,不是质数
}
}
return true; // 是质数
}
int main() {
int n;
while (scanf("%d", &n) != EOF) {
if (Judge(n)) {
printf("yes\n"); // 是质数输出 yes
} else {
printf("no\n"); // 不是质数输出 no
}
}
return 0;
}
心得体会:
注意的点应该放在 int bound = sqrt(x); 确定判断上界!!!仔细想一下确实,还有小于2必定不是,所以在单独的函数开始的时候就可以把他放在最后。
素数(北航上机题)
题目描述:
代码表示:
#include <bits/stdc++.h>
using namespace std;
const int MAXN = 10001;
vector<int> prime; // 保存质数
bool isPrime[MAXN]; // 标记数组
void Initial() {
//初始化质数
for (int i = 0; i < MAXN; ++i)
{ // 初始化
isPrime[i] = true;
}
//将 0 和 1 标记为非质数。
isPrime[0] = false;
isPrime[1] = false;
//再次循环遍历从 2 到 MAXN-1 的所有数字。
for (int i = 2; i < MAXN; ++i) {
if (!isPrime[i]) { // 非质数则跳过
continue;
}
prime.push_back(i);//当前质数 i 加入到 prime 容器中
for (int j = i * i; j < MAXN; j += i) {
isPrime[j] = false; // 质数的倍数为非质数
}
}
}
int main() {
Initial();
int n;
while (scanf("%d", &n) != EOF) {
bool isOutput = false; // 判断是否有输出
for (int i = 0; i < prime.size() && prime[i] < n; ++i) {
if (prime[i] % 10 == 1) { // 判断个位是否为 1
isOutput = true;
printf("%d ", prime[i]);
}
}
if (!isOutput) {
printf("-1");
}
printf("\n");
}
return 0;
}
心得体会:
1、if (prime[i] % 10 == 1)
是用来判断当前循环到的质数 prime[i]
的个位数字是否为 1。具体来说,当一个质数除以 10 取模的结果等于 1 时,就满足这个条件。
例如,假设当前循环到的质数是 31。那么,31 % 10 的结果是 1,因此它符合条件。而当质数是 37 时,37 % 10 的结果是 7,不等于 1,因此不符合条件。
2、isPrime
的作用是在初始化时标记每个数字是否为质数,以便后续的操作中能够快速判断一个数是否为质数。通过标记数组,可以在程序运行过程中避免重复计算某个数是否为质数,提高程序的效率。
具体来说:
1)在初始化时,通过标记数组将所有数字标记为质数或非质数。
2)在找出质数并存储到 prime
容器中时,利用标记数组跳过已经标记为非质数的数字,减少不必要的计算。
3)在输出符合条件的质数时,也可以利用标记数组快速判断一个数是否为质数。
[蓝桥杯 2023 省 B] 接龙数列
题目描述
对于一个长度为 K 的整数数列:1,2,…,A1,A2,…,AK,我们称之为接龙数列当且仅当 Ai 的首位数字恰好等于 Ai−1 的末位数字(2≤i≤K)。
例如 12,23,35,56,61,11 是接龙数列;12,23,34,56 不是接龙数列,因为 56 的首位数字不等于于 34 的末位数字。所有长度为 1 的整数数列都是接龙数列。
现在给定一个长度为 N 的数列A1,A2,…,AN,请你计算最少从中删除多少个数,可以使剩下的序列是接龙序列?
输入格式
第一行包含一个整数 N。
第二行包含 N 个整数A1,A2,…,AN。
输出格式
一个整数代表答案。
代码表示:
#include<bits/stdc++.h>
using namespace std;
int n,m,i,dp[10];
string a;//用字符串存储,便于运算
int main(){
ios::sync_with_stdio(false);
cin>>n;
for(i=n;i--;){
cin>>a;
dp[a[a.size()-1]-48]=max(dp[a[a.size()-1]-48],dp[a[0]-48]+1);//如果a有贡献
}
for(i=0;i<=9;i++)m=max(m,dp[i]);//取最大值
cout<<n-m;
}
心得体会:
明天学完动态规划再来看(((φ(◎ロ◎;)φ)))(((φ(◎ロ◎;)φ)))