藍橋杯
+++
#include <iostream>
#include <vector>
#include <algorithm>
#include <string>
using namespace std;
//常使用的頭文件
動態規劃
小藍在黑板上連續寫下從 11 到 20232023 之間所有的整數,得到了一個數字序列: S=12345678910111213…20222023
這里問題在于要記錄下s 就要拼接數字到之前記錄的后面 但是strcat
只可以拼接字符串 不可以拼接數字 因此要轉化
#include <bits/stdc++.h>
#define int long long //這里的long long 是64位的整數
using namespace std; signed main() { //與int 差不多 但是表示返回一個有符號的整數 而且方式更簡潔 而且前面使用了define int long long string s;int dp[4] = {0};for (int i = 0; i <= 2023; i++) {s += to_string(i);}for (int i = 0; i < s.size(); i++) {if (s[i] == '2') {dp[0]++;dp[2] += dp[1];} else if (s[i] == '0') {dp[1] += dp[0];} else if (s[i] == '3') {dp[3] += dp[2];}}cout << dp[3] << endl;}
c語言方法sprintf(temp.%d,i);
strcat(s,temp);
// sprintf(要存儲的地方,要轉變為字符串之前的形式,原本的數據)
// strcat(要存儲的最終地方要存儲的地方,)
時間戳
#include <stdio.h>
#include <time.h>int main() {// 1. 讀取打卡記錄文件 FILE *fp = fopen("record.txt", "r");time_t t[1000]; // 假設最多存1000條打卡記錄 char line[30]; // 存儲每行時間字符串 int cnt = 0; // 記錄實際讀取的打卡次數 // 2. 逐行解析時間 while (fgets(line, sizeof(line), fp)) {struct tm tm = {0};sscanf(line, "%d-%d-%d %d:%d:%d",&tm.tm_year, &tm.tm_mon, &tm.tm_mday, &tm.tm_hour, &tm.tm_min, &tm.tm_sec); tm.tm_year -= 1900; // 年份從1900開始算 tm.tm_mon -= 1; // 月份范圍0-11 t[cnt++] = mktime(&tm); // 轉為秒級時間戳 }fclose(fp);// 3. 冒泡排序時間戳(簡單但直觀)for (int i = 0; i < cnt; i++) for (int j = i+1; j < cnt; j++)if (t[i] > t[j]) {time_t tmp = t[i];t[i] = t[j];t[j] = tmp;}// 4. 計算總工作時長 long sum = 0;for (int i = 0; i < cnt; i += 2) // 每兩個為一組(上班+下班)sum += t[i+1] - t[i]; // 下班時間 - 上班時間 printf("2022年總工作時長:%ld秒\n", sum);return 0;
}
票據問題(c++)
每張票據有唯一的 ID 號,全年所有票據的 ID 號是連續的,但 ID 的開始數碼是隨機選定的。因為工作人員疏忽,在錄入 ID 號的時候發生了一處錯誤,造成了某個 ID 斷號,另外一個 ID 重號。
你的任務是通過編程,找出斷號的 ID 和重號的 ID。
數據保證斷號不可能發生在最大和最小號。
輸入格式
一個整數 N(N<100) 表示后面數據行數,接著讀入 N 行數據,每行數據長度不等,是用空格分開的若干個(不大于 100100 個)正整數(不大于 10^5),每個整數代表一個 ID 號。
輸出格式
要求程序首先輸入要求程序輸出 11 行,含兩個整數 m,n,用空格分隔,其中,m 表示斷號 ID,n 表示重號 ID。
輸入輸出樣例
輸入
2
5 6 8 11 9
10 12 9
輸出
7 9
#include<bits/stdc++.h>
using namespace std;
#define N 10010
int n;
int main()
{int cnt;cin >> cnt;vector<int>a;string line;getline(cin,line); //吃掉一個回車int t;for(int i=0;i<cnt;i++){getline(cin,line); 。。讀取一行stringstream ssin(line); //將字符串轉化為數字while(ssin >> t){ //將ssin 中的東西給到t 中 并且由t給到aa.push_back(t);}}sort(a.begin(), a.end());int res1, res2;for (int i = 1; i < a.size(); i++){if (a[i] == a[i - 1]) res2 = a[i];//重號if(a[i]>a[i-1]+1)res1 =a[i-1]+1;}cout << res1 << " " << res2 << endl;return 0;
}
卡片問題
小藍有很參考數字卡片,每張卡片上都是數字 0 到 9。
小藍準備用這些卡片來拼一望數字,他想從 1 開始拼出正整數,每拼一個,就保存起來,卡片就不準用來拼其它數字了。
小藍想知道自己能從 1 拼到多少。
例如,當小藍有 30 張卡片,其中 0 到 9 各 3 張,則小藍可以拼出 1 到 10,但是在拼 11 時卡片 1 已經只有一張了,不夠拼出 11。
現在小藍手里有 0 到 9 的卡片各 2021 張,共 20210 張,請問小藍可以從 1 拼到多少?
#include <iostream>
using namespace std;
int main(){int i,t,a[9];for(i=0;i<10;i++){a[i] = 2021;}for(i=1;;i++){t = i;while(t){if(a[t%10]==0){ //這是獲取要組成數字的數的個位 例如卡片10 有0 和 1 組成cout << i-1;return 0;
}a[t%10]--; //每次使用后卡片數-1t /= 10; //獲取110 中的1
}}return 0;}
貨物擺放 求非常大的n=a *b *c的方法
#include<iostream>
#include<algorithm>
using namespace std;
typedef long long LL;
LL yue[101000],cnt;int main()
{LL n=2021041820210418;for(LL i=1;i<=n/i;i++){if(n%i==0){yue[++cnt]=i;if(i*i!=n)yue[++cnt]=n/i;}}//sort(yue+1,yue+cnt+1);//for(int i=1;i<=cnt;i++)cout<<yue[i]<<" ";//cout<<cnt;int ans=0;for(int i=1;i<=cnt;i++){for(int j=1;j<=cnt;j++){if(n%(yue[i]*yue[j])==0)ans++;}}cout<<ans;return 0;
}
我的
#include<bits/stdc++.h>using namespace std;
typedef long long ll;
ll cnt[101000],yue=0;
int main(){ll n= 2021041820210418;int i;for(ll i=1;i<=n/i;i++){if(n%i==0){cnt[yue++]=i;if(i*i!=n){cnt[yue++] = n/i;}}}int cns = 0;for(int j=0;j<yue;j++){for(int k=0;k<yue;k++){if(n%(cnt[j]*cnt[k])==0){cns++;}}}cout << cns;return 0;}
路徑(貪心)
基礎:喝水問題
#include<bits/stdc++.h>
#include <iostream>
using namespace std;int main()
{int a[201] = {0};int n,s=0,r,i;cin >> n >> r; //r是水龍頭的數量 N是有n個人for(i=1;i<=n;i++){cin >> a[i];}sort(a,a+n);for(i=1;i<=n;i++){if(i>=r+1){a[i] = a[i] + a[i-r];}s = s + a[i];}cout << s;return 0;}
#include<iostream>
#include<algorithm>
#include<cstring>
#include<cmath>
using namespace std;
const int N=2510;
int g[N][N],dist[N],st[N];
int n=2021;
int gcd(int a, int b)
{return b ? gcd(b, a % b) : a; //return 判斷式? 選擇一 : 選擇二
}
int lcm(int a,int b){return a*b/gcd(a,b);
}int dijkstra(){memset(dist,0x3f,sizeof dist);dist[1]=0;for(int i=1;i<=n;i++){int t=-1;for(int j=1;j<=n;j++){if(!st[j] && (t==-1 || dist[j]<dist[t]))t=j;}st[t]=1;for(int j=1;j<=n;j++){dist[j]=min(dist[j],dist[t]+g[t][j]); //返回兩個參數中的最小值 }}return dist[n];
}
int main(){for(int i=1;i<=n;i++)for(int j=1;j<=n;j++){if(i!=j){if(fabs(i-j)<=21){ //計算絕對值g[i][j]=lcm(i,j);g[j][i]=lcm(i,j);}else{g[i][j]=0x3f3f3f3f;g[j][i]=0x3f3f3f3f;}}}cout<<dijkstra();//cout<<0x3f3f3f3f;return 0;
}//dist[i]:從起點(這里是節點 1)到節點 i 的當前最短路徑長度。
受不了了 這個我是在理解不了
過河卒問題
精簡(沒馬的)
#include<bits/stdc++.h>
#include <iostream>
using namespace std;int main()
{int a[30][30] = {0}; //坐標int n,m;cout << "請你輸入嗎馬所在的位置";cin >> n >> m;for(int i=0;i<=n;i++){for(int j=0;j<=m;j++) {if(i==0&&j==0){continue;}if(i==0||j==0){a[i][j] = 1;}else{a[i][j] = a[i-1][j] + a[i][j-1];} }
}cout << a[n][m];return 0;
}
#include <stdio.h>
#include <stdlib.h>#include <math.h>
#define OK 1
#define ERROR 0typedef struct Node { //創建結構體int data;struct Node *next;
} Node, *Snode;Snode Createlist() { //創建一個鏈表Snode head = NULL;Snode next = NULL;int num;while (1) {scanf("%d", &num);if (num == -1) {break;}Snode newNode = (Snode)malloc(sizeof(Node));if (newNode == NULL) {printf("分配內存失敗");exit(1);}newNode->data = num;newNode->next = head;head = newNode;}return head;
}Snode mergeList(Snode T1, Snode T2) { //合并兩個鏈表Snode head = NULL;Snode tail = NULL;while (T1 != NULL && T2 != NULL) {if (T1->data > T2->data) { //這里降序將數據合并if (head == NULL) {head = T1;tail = T1;} else {tail->next = T1;
// tail = tail->next;tail = T1;}T1 = T1->next;} else {if (head == NULL) {head = T2;tail = T2;} else {tail->next = T2;
// tail = tail->next;tail = T2;}T2 = T2->next;}}if (T1 != NULL) { //這里處理剩余節點if (head == NULL) {head = T1;} else {tail->next = T1;}}if (T2 != NULL) {if (head == NULL) {head = T2;} else {tail->next = T2;}}return head;
}void printList(Snode list) { //這里打印鏈表Snode head = list;while (head != NULL) {printf("%d ", head->data);head = head->next;}printf("\n");}void freeList(Snode head) {Snode temp;while (head != NULL) {temp = head;head = head->next;free(temp);}
}int main() { //主函數的使用printf("創建你的第一個鏈表(輸入-1結束):");Snode T1 = Createlist();printf("創建你的第二個鏈表(輸入-1結束):");Snode T2 = Createlist();printf("\n");printf("你的第一個鏈表中元素為:");printList(T1);printf("\n");printf("你的第二個鏈表的元素為:");printList(T2);Snode mergeT = mergeList(T1, T2);printf("\n");printf("兩個鏈表合并之后(降序排列)為");printList(mergeT);freeList(mergeT);return 0;}
二分法簡便
#include<algorithm>
using namespace std;
int main(){{int data[200];for(int i = 0 ; i < 200 ; i ++)data[i] = 4 * i + 6;int n;cin>>n;cout<<lower_bound(data,data+200,n)-data<<endl;return 0;
}
正常二分法
#include <iostream>
using namespace std;int main() {int arr[200];for(int i = 0; i < 200; i++) arr[i] = 4 * i + 6;int n;cin >> n;int mid, left, right;left = 0;right = 199; // 數組最后一個索引while (left <= right) {mid = (left + right) / 2;if (arr[mid] == n) {cout << mid << endl;return 0; // 找到后退出} else if (arr[mid] < n) {left = mid + 1; // 跳過 mid} else {right = mid - 1; // 跳過 mid}}cout << "-1" << endl; // 未找到return 0;
}
這個運行2ms 但是正常的循環便利要29ms
輸入一端數組讓他從大到小 小到大排序
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;int main() {int N;cin >> N;vector<int>a(N); //這里注意是()for (int i = 0; i < N; i++) {cin >> a[i];}sort(a.begin(), a.end()); //先begin 后endfor (int num : a) {cout << num << " ";}cout << endl;sort(a.begin(), a.end(), greater<int>()); for (int num : a) {cout << num << " ";}return 0;
}
輸入一串數字得到最大值和最小值還有平均值
#include <iostream>
#include <iomanip>
#include<algorithm>
#include<vector>
using namespace std;
int main()
{int N,i;cin >> N;vector<int>a(N);for(i=0;i<N;i++){cin >> a[i]; //注意endl只適用于cout 不適用于cin}int min ,max;float ave,sum=0;min = a[0];max = a[0];for(i=0;i<N;i++){if(a[i]<min){min = a[i];}if(a[i]>max){max = a[i];}sum+=a[i];}ave = sum/N;cout << max << endl<< min << endl<<fixed << setprecision(2)<<ave<<endl; //這里的注意點是c++中想要輸出的小數精度為2時候該怎么寫return 0;
}
簡便的方法
#include <bits/stdc++.h> //這是一個萬能頭文件 可以省去很多麻煩using namespace std;int main() {vector<int>a;int N;cin >> N;a.resize(N); //這個作用是給數組a分配你輸入的N的空間int i;for (i = 0; i < N; i++) {cin >> a[i];}cout << *max_element(a.begin(), a.end()) << endl;cout << *min_element(a.begin(), a.end()) << endl;double sum;for (int ele : a) { //這里將a容器中的元素一個個給ele然后加入到sum中sum += ele;}cout << fixed << setprecision(2) << sum / N; return 0;}
CLZ 銀行問題
題目
題目描述
CLZ 銀行只有兩個接待窗口,VIP 窗口和普通窗口,VIP 用戶進入 VIP 窗口排隊,剩下的進入普通窗口排隊。現有 M 次操作,操作四種類型,如下:
IN name V:表示一名叫 name 的用戶到 VIP 窗口排隊
OUT V:表示 VIP 窗口隊頭的用戶離開排隊
IN name N:表示一名叫 name 的用戶到普通窗口排隊
OUT N:表示普通窗口隊頭的用戶離開排隊
求M 次操作結束后 VIP 窗口隊列和普通窗口隊列中的姓名。
輸入描述
第一行是一個整數 M(1≤M≤1000),表示一共有 M 次操作。
第二行到第 M+1 行輸入操作,格式如下:
IN name V
OUT V
IN name N
OUT N
輸出描述
輸出M 次操作后 VIP 窗口隊列和普通窗口隊列中的姓名(從頭到尾),先輸出 VIP 窗口隊列后輸出普通窗口隊列。
示例 1
輸入
5
IN xiaoming N
IN Adel V
IN laozhao N
OUT N
IN CLZ V
輸出
Adel
CLZ
laozhao
————————————————
#include <bits/stdc++.h>using namespace std;int main() {int N;cin >> N;string a;queue <string>n, v;for (int i = 0; i < N; i++) {cin >> a;if (a == "IN") { //這里分為兩類 一類IN 一類out 然后又細分兩類一個vip身份 一個正常身份string name, p;cin >> name >> p;if (p == "V")v.push(name);else n.push(name);} else { //注意這里要有if 因為else 后面不可以直接跟你要判斷的條件string p;cin >> p;if (p == "V")v.pop();elsen.pop();}}while (v.size()) { //這里將v中的內容輸出cout << v.front() << endl;v.pop(); //每次輸出之后將這個元素彈出}while (n.size()) {cout << n.front() << endl;n.pop();}return 0;}
分糖果
題目
問題描述
最近暑期特訓算法班的同學們表現出色,他們的老師肖恩決定給他們分發糖果。肖恩購買了 n 個不同種類的糖果,用小寫的阿拉伯字母表示。每個糖果必須分發給一個同學,并且每個同學至少要分到一個糖果。同學們的開心程度定義為他們所分到的糖果組成的字符串 s[i] 的字典序。肖恩希望同學們的開心程度相差盡量小,因此他要找到一種方案,使得所有糖果組成的字符串中字典序最大的字符串盡可能小。請輸出能夠實現字典序最小可能的max(s[1],s[2],s[3],…,s[x]) 。
輸入描述
第一行輸入兩個整數
n 和x ,分別表示有 n 個糖果 x 個同學。
第二行輸入一個長度為 n 的字符串S S[i] 表示第 i 個糖果的種類。
數據保證
1≤n≤10 ^6 ,1≤x≤n,S[i]∈[ ′ a ′ , ′ z ′ ] 。
輸出描述
輸出一個字符串,為所有糖果組成的字符串中字典序最大的字符串最小的可能值。
樣例輸入
6 2
caabdc
樣例輸出
abccd
說明
一個最優分配方案是一個同學拿到 abccd ,一個同學拿到 a 。
合并果子(貪心+最小成本)
題目描述
在一個果園里,多多已經將所有的果子打了下來,而且按果子的不同種類分成了不同的堆。多多決定把所有的果子合成一堆。每一次合并,多多可以把兩堆果子合并到一起,消耗的體力等于兩堆果子的重量之和。可以看出,所有的果子經過 n?1 次合并之后,就只剩下一堆了。多多在合并果子時總共消耗的體力等于每次合并所耗體力之和。因為還要花大力氣把這些果子搬回家,所以多多在合并果子時要盡可能地節省體力。假定每個果子重量都為 1,并且已知果子的種類數和每種果子的數目,你的任務是設計出合并的次序方案,使多多耗費的體力最少,并輸出這個最小的體力耗費值。
例如有 3 種果子,數目依次為 1,2,9。可以先將 1、2 堆合并,新堆數目為 3,耗費體力為 3。接著,將新堆與原先的第三堆合并,又得到新的堆,數目為12,耗費體力為 12。所以多多總共耗費體力 =3+12=15。可以證明 15 為最小的體力耗費值。
輸入描述
輸入兩行。
第一行是一個整數 n(1≤n≤10^4 ),表示果子的種類數。
第二行包含 n 個整數,用空格分隔,第 i 個整數 (1≤a i≤2×10 4 ) 是第 i 種果子的數目。
輸出描述
輸出一個整數,也就是最小的體力耗費值。輸入數據保證這個值小于 2^31 。
輸入輸出樣例
示例 1
輸入
3
1 2 9
輸出
15
————————————————
芝士:
priority 是一個堆
priority_queue<T,Container,Compare> pq; //pq 是一個名字 優先隊列的對象名字
- T 是存儲的數據類型 如 int long long
- Container 是底層容器 一般是vector
- Compare 是比較器 決定大堆還是小堆
- greater 頂部是小堆
- less 頂部是最大堆
push(x):插入元素 x,時間復雜度 O(log n)。
top():返回頂部元素(最小或最大值,取決于堆類型),時間復雜度 O(1)。
pop():刪除頂部元素,時間復雜度 O(log n)。
size():返回隊列中元素個數,時間復雜度 O(1)。
empty():檢查隊列是否為空,時間復雜度 O(1)。
#include <bits/stdc++.h>
using namespace std;int main() {int n;cin >> n;int f, e; long long sum = 0;priority_queue<long long, vector<long long>, greater<long long>>pq;for (int i = 0; i < n; i++) {int t;cin >> t; //這里逐個將堆中的元素錄入pq.push(t);}while (pq.size() > 1) {f = pq.top(); pq.pop();e = pq.top();pq.pop(); //分別將堆中兩個最小的數字取出sum += (f + e); //計算兩個數字的和pq.push(f + e); //將取出的兩個數字的和再放入堆中便于之后一起算最小成本}cout << sum;return 0;
}
掃雷問題
拓展給數組每個元素賦值某個值的方法>
vector <int>a(N,0) //將一維數組中每個元素賦值為0
vector<vector<int>> a(n,vector<int>(m,0)) //給n , m的二維數組每個元素賦值為0
題目描述
在一個 n 行 m 列的方格圖上有一些位置有地雷,另外一些位置為空。請為每個空位置標一個整數,表示周圍八個相鄰的方格中有多少個地雷。
輸入描述
輸入的第一行包含兩個整數 n,m。第 2 行到第 n+1 行每行包含 m 個整數,相鄰整數之間用一個空格分隔。如果對應的整數為 0,表示這一格沒有地雷。如果對應的整數為 1,表示這一格有地雷。其中,1≤n,m≤100 分鐘后還是在當天。
輸出描述
輸出 n 行,每行 m 個整數,相鄰整數之間用空格分隔。對于沒有地雷的方格,輸出這格周圍的地雷數量。對于有地雷的方格,輸出9。
輸入輸出樣例
示例 1
輸入
3 4
0 1 0 0
1 0 1 0
0 0 1 0
輸出
2 9 2 1
9 4 9 2
1 3 9 2
這道題的訣竅就是設置數組的時候設置一個可以把原本數組包圍起來的數組 也就是頂部加一行 底部加一行 左邊加一列 右邊加一列 之后通過循環逐個索引
#include <bits/stdc++.h>using namespace std;int main() {int n, m, count = 0;cin >> n >> m;vector<vector<int>> a(n + 2, vector<int>(m + 2, 0)); //初始化數組 并且其中的值都設置為0vector<vector<int>> b(n + 2, vector<int>(m + 2, 0));for (int i = 1; i < n + 1; i++) {for (int j = 1; j < m + 1; j++) {cin >> a[i][j];}}for (int i = 1; i < n + 1; i++) {for (int j = 1; j < m + 1; j++) {if (a[i][j] == 1) {b[i][j] = 9;} else {for (int p = -1; p < 2; p++) {for (int q = -1; q < 2; q++) {if (a[i + p][j + q] == 1) {count++;}}}b[i][j] = count;}count = 0;}}for (int i = 1; i < n + 1; i++) {for (int j = 1; j < m + 1; j++) {cout << b[i][j] << " ";}cout << endl; //這里注意在第一個for循環之后換行}return 0;}
灌溉問題
題目描述
小藍負責花園的灌溉工作。
花園可以看成一個 n 行 m 列的方格圖形。中間有一部分位置上安裝有出水管。小藍可以控制一個按鈕同時打開所有的出水管,打開時,有出水管的位置可以被認為已經灌溉好。每經過一分鐘,水就會向四面擴展一個方格,被擴展到的方格可以被認為已經灌溉好。即如果前一分鐘某一個方格被灌溉好,則下一分鐘它上下左右的四個方格也被灌溉好。給定花園水管的位置,請問 k 分鐘后,有多少個方格被灌溉好?
輸入描述
輸入的第一行包含兩個整數 n,m。
第二行包含一個整數 t,表示出水管的數量。
接下來 t 行描述出水管的位置,其中第 i 行包含兩個數r,c 表示第 r 行第 c 列有一個排水管。
接下來一行包含一個整數 k。
其中,1≤n,m≤100,1≤t≤10,1≤k≤100。
輸出描述
輸出一個整數,表示答案。
輸入輸出樣例
示例 1
輸入
3 6
2
2 2
3 4
1
輸出
9
這個問題有個關鍵就是必須要有兩個數組 不可以僅僅對著一個數組操作 因為操作的過程會使條件改變 導致循環和判斷中的不對
#include <bits/stdc++.h>using namespace std;int main() {int n, m;cin >> n >> m;vector<vector<int>> a(n + 2, vector<int>(m + 2, 0));
//初始化主數組int x;cin >> x;for (int i = 1; i <= x; i++) {int l, k;cin >> l >> k;a[l][k] = 1;
//給有水管的地方賦值為1}int fen;cin >> fen;vector<vector<int>> t(n + 2, vector<int>(m + 2, 0));for (int i = 1; i < n + 1; i++) {for (int j = 1; j < m + 1; j++) {t[i][j] = a[i][j];}}for (int s = 1; s <= fen; s++) {for (int i = 1; i < n + 1; i++) {for (int j = 1; j < m + 1; j++) {if (a[i][j] == 1) {t[i - 1][j] = 1;t[i][j - 1] = 1;t[i + 1][j] = 1;t[i][j + 1] = 1;} //給上下左右面澆樹水 也就是賦值為1 }}for (int i = 1; i < n + 1; i++) {for (int j = 1; j < m + 1; j++) {a[i][j] = t[i][j];}}}int count = 0;for (int i = 1; i < n + 1; i++) {for (int j = 1; j < m + 1; j++) {if (a[i][j] == 1) {count++;}}}cout << count;return 0;
}
十六進制轉化為十進制
請問十六進制數 2021ABCD 對應的十進制是多少?
解決 :先將十六進制轉化為二進制 再將二進制轉化為十進制
#include <stdio.h>
#include <math.h>int main() {long long int a[32] = {0b00100000001000011010101111001101} ;//唯一需要注意的就是為了確保輸入的是十進制 所以需要前面加一個0blong long int x, sum = 0;for (int i = 0; i < 32; i++) {x = a[i] * pow(2, i);sum += x;}printf("%lld", sum);return 0;
}
進制轉化升階
題目描述
給定一個 N 進制數 S,請你將它轉換為 M 進制。
輸入描述
第一行為一個整數 T,表示測試數據數量。 (1≤T≤10^5)每個測試用例包含兩行,第一行包含兩個整數 N,M。
第二行輸入一個字符串 S,表示 N 進制數。
數據范圍保證:2≤N,M≤16,若 N≥10,則用 A~F 表示字碼 10~15。保證 S 對應的十進制數的位數不超過 10。
輸出描述
輸出共 T,每行表示一組數據的答案。
輸入樣例
2
2 10
10101
11 2
1793A5068
輸出樣例
21
10101111001010100111010101011
這里解決問題的有幾個關鍵
- 任何進制轉化為另一個進制 要先轉化為十進制
- 那么 因為輸入的一連串數字是string 類型如果直接 所以要先通過循環轉化為
- 再通過循環轉化為十進制
- 之后再使用while語句中的取余和除 得出對應的進制數
- 注意的是string 可以使用s[i] 索引其中的元素
#include <bits/stdc++.h>
using namespace std;int main() {char ch[] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'};int T;int a[50];cin >> T;while (T--) {int N, M;cin >> N >> M; //幾進制到幾進制的轉化string s;cin >> s; //目標字符for (int i = 0; i < s.size(); i++) {if (s[i] >= '0' && s[i] <= '9') //單引號是指ASCII值a[i + 1] = s[i] - '0';elsea[i + 1] = s[i] - 'A' + 10; //將string 類型轉化為數字類型}
//161514321long long x = 0;for (int i = 1; i <= s.size(); i++)x = x * N + a[i]; //轉化為十進制string ans;while (x) {ans += ch[x % M]; //這里的+=是字符串的拼接x = x / M;}reverse(ans.begin(), ans.end());cout << ans << endl;}return 0;}
字母數
請找到一個大于 20222022 的最小數,這個數轉換成二進制之后,最低的 66 個二進制位全為 00 。
請將這個數的十進制形式作為答案提交。
#include <bits/stdc++.h>
using namespace std;int main() {int x = 2023, temp, t;for ( ; x <= 10000; x++) {temp = x;t = x;string ans;while (temp) {ans += temp % 2 + '0';temp = temp / 2;} //轉化為2進制reverse(ans.begin(), ans.end()); //倒著排序bool a = true;if (ans.size() > 6) {for (int i = ans.size() - 6; i < ans.size(); i++) {if (ans[i] != '0') { //注意這里是減去' ' 因為ans的類型是ststring 類型a = false;break; //判斷最低六位是否為0}}} else {a = false;}if (a) {cout << t;break;}}return 0;}
背包問題
拓展知識
max(a, b) 返回 a 和 b 中較大的值。
#include <bits/stdc++.h>
using namespace std;const int N = 100;
int n, weightBag;
int weight[N], value[N];int select(int i, int j) { //i 是第幾個物品 J是物品重量int result;if (i == n) { //檢查有沒有該物品return result; } else if (j < weight[i]) { //要是物品的重量大于背包的容量result = select(i + 1, j);} else { //背包有該物品且物品的重量小于背包的容量 接下來判斷該不該挑選這個物品result = max(select(i + 1, j), select(i + 1, j - weight[i]) + value[i]);}return result;}int main() {cout << "請輸入物品的數量和背包的重量" << endl;cin >> n >> weightBag; // 有幾個物品 背包的重量是多少cout << "請分別輸入物品的重量" << endl;for (int i = 0; i < n; i++) {cin >> weight[i];}cout << "請分別輸入物品的價值" << endl;for (int i = 0; i < n; i++) {cin >> value[i];}cout << select(0, weightBag) << endl;return 0;}
三元便利數組
(可以把一堆數字中按照三個一組全部便利一遍)
for(i=0;i<N-2;i++){for(j=i+1;j<N-1;j++){for(k=j+1;k<N;k++){}}
}
+++
memset函數
(將一個數組或內存中的數全部變為0,這也叫做初始化)
場景:例如要讓你走在一個棋盤之中,你走過的路徑都要標記為1,沒有走過的都是0,那么你一開始就要memset();
memset(要設置的區域的起始地址,要設置的value,sezeof(數組))//要設置的字節數
+++
dfs函數
(深度遍歷要走的路徑,直到找到滿意的路徑,使用遞歸和回溯)
場景:例如要讓你走在一個棋盤當中,你要走每一個格子,并且要找到出去的最優解(格子中有丈量你走的價值的東西),這時候就要用到dfs
拼接函數
模仿strcat
#include <stdio.h>
#include <stdlib.h>
#include <string.h>int main() {int i;char x[100000] = ""; // 用于存儲拼接結果的字符數組// 注意:連接數字時需要先把數字轉成字符串for (i = 1; i <= 2023; i++) {char temp[50]; // 臨時存儲數字的字符串sprintf(temp, "%d", i); // 將數字 i 轉換為字符串strcat(x, temp); // 拼接到 x 后面// 如果需要將 i++ 放在不同的字符串中,可以這樣做sprintf(temp, "%d", i + 1); // 將 i+1 轉換為字符串strcat(x, temp); // 拼接到 x 后面}// 打印最終結果printf("%s\n", x); return 0;
}/*sprintf函數用于將某種類型轉化為字符類型,因為strcat函數是要拼接字符串類型的數據的sprintf(轉化的東西所在的位置,轉化前的類型,要轉化的內容)
]) + value[i]);
}return result;
}
int main() {
cout << “請輸入物品的數量和背包的重量” << endl;
cin >> n >> weightBag; // 有幾個物品 背包的重量是多少
cout << “請分別輸入物品的重量” << endl;
for (int i = 0; i < n; i++) {
cin >> weight[i];
}
cout << "請分別輸入物品的價值" << endl;
for (int i = 0; i < n; i++) {cin >> value[i];
}
cout << select(0, weightBag) << endl;return 0;
}
## 三元便利數組(可以把一堆數字中按照三個一組全部便利一遍)```c
for(i=0;i<N-2;i++){for(j=i+1;j<N-1;j++){for(k=j+1;k<N;k++){}}
}
+++
memset函數
(將一個數組或內存中的數全部變為0,這也叫做初始化)
場景:例如要讓你走在一個棋盤之中,你走過的路徑都要標記為1,沒有走過的都是0,那么你一開始就要memset();
memset(要設置的區域的起始地址,要設置的value,sezeof(數組))//要設置的字節數
+++
dfs函數
(深度遍歷要走的路徑,直到找到滿意的路徑,使用遞歸和回溯)
場景:例如要讓你走在一個棋盤當中,你要走每一個格子,并且要找到出去的最優解(格子中有丈量你走的價值的東西),這時候就要用到dfs
拼接函數
模仿strcat
#include <stdio.h>
#include <stdlib.h>
#include <string.h>int main() {int i;char x[100000] = ""; // 用于存儲拼接結果的字符數組// 注意:連接數字時需要先把數字轉成字符串for (i = 1; i <= 2023; i++) {char temp[50]; // 臨時存儲數字的字符串sprintf(temp, "%d", i); // 將數字 i 轉換為字符串strcat(x, temp); // 拼接到 x 后面// 如果需要將 i++ 放在不同的字符串中,可以這樣做sprintf(temp, "%d", i + 1); // 將 i+1 轉換為字符串strcat(x, temp); // 拼接到 x 后面}// 打印最終結果printf("%s\n", x); return 0;
}/*sprintf函數用于將某種類型轉化為字符類型,因為strcat函數是要拼接字符串類型的數據的sprintf(轉化的東西所在的位置,轉化前的類型,要轉化的內容)