日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > c/c++ >内容正文

c/c++

蓝桥杯大赛决赛整理合集(B组C/C++)

發布時間:2023/12/29 c/c++ 29 豆豆
生活随笔 收集整理的這篇文章主要介紹了 蓝桥杯大赛决赛整理合集(B组C/C++) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

藍橋杯大賽決賽整理合集(B組C/C++)

根據大綱梳理一遍,也在全文最后補充了最幾年的決賽真題,全文基于C++編寫,希望對你有所幫助
關于省賽的反思:
1.我的Code::Block 20.03在機房的電腦調不出來(我決定還是用DEV)
2.暴力算法枚舉不要指望學校機房的CPU
3.注意數據的規模,寫完一部分代碼塊記得調試運行一下
ps:真題做下來不難發現小明是個究極強迫癥QVQ,期末沒有什么時間寫,還要英語四級,提前cue借口,但還是加油!!
——以上是2021年的整理
經過寒假對考研數據結構的復習,對算法有了新的感悟) 。
繼續整理的棧 隊列 樹 圖 排序

大綱要求

C/C++程序設計基礎:包含使用 C/C++編寫程序的能力。該部分不考查選手對某一語法的理解程度,選手可以使用自己喜歡的語句編寫程序。選手可在 C 語言程序中使用標準 C 的庫函數,在 C++語言程序中使用標準 C++的庫函數(包括 C 庫、STL 等)。
計算機算法:枚舉、排序、搜索、計數、貪心、動態規劃、圖論、數論、博弈論*、概率論*、計算幾何*、字符串算法等。
數據結構:數組、對象/結構、字符串、隊列、棧、樹、圖、堆、平衡樹/線段樹、復雜數據結構*、嵌套數據結構*等。

一、STL

1.vector容器(單端數組)

vector容器可以動態地擴展(原數據拷貝新空間)

#include<iostream> #include<vector> using namespace std; int main(){vector<int> v1;//默認構造v1.push_back(1);//尾部插入 v1.pop_back();//尾部刪除最后一個元素v1.insert(v1.begin(),100);//在迭代器指定位置插入數據v1.erase(v1.begin());//刪除迭代器指定位置v1.clear();//清空 cout<<v1.capacity()<<endl;//輸出容量 cout<<v1.size()<<endl;//元素個數 v1.resize(15,100);//指定默認填充值拓展容量cout<<v1[0]<<" "<<v1[1]<<endl; //輸出數據vector<int> v2(v1.begin(),v1.end());//區間方式構造vector<int> v3(10,100);//v3中有10個100vector<int> v4(v3);//拷貝構造if(v1.empty()){//判斷是否為空 cout<<"空"<<endl;}v1.reserve(100);//預留空間,元素不可以訪問 v1.swap(v2);//交換兩個容器中的數據 vector<int>(v).swap(v)//巧用可以壓縮空間return 0; }

2.queue容器(隊列——先進先出)

一般會結合bfs使用

#include<iostream> #include<queue> using namespace std; int main(){queue<int> q;q.push(1);//入隊q.push(2); cout<<"隊列是否為空:"<<q.empty()<<endl;cout<<"隊頭元素是:"<<q.front()<<endl;cout<<"隊尾元素是:"<<q.back()<<endl;q.pop();//出隊 cout<<"隊列元素個數:"<<q.size()<<endl;return 0; }

3.map/multimap容器(關聯式——二叉樹)

可以很方便地用Key值查找value值
map容器:不允許有重復key值
multimap容器:允許有重復key值

#include<iostream> #include<map> using namespace std; class cmp{//指定降序插入 public:bool operator()(int v1,int v2){return v1>v2;} }; int main(){map<int,int> m1;//創建map容器 map<int,int> m2(m1);//拷貝構造 map<int,int,cmp> m3;//按照指定規則排序 (默認按照key的升序插入)m1.insert(pair<int,int>(2,30));//插入數據 m1.insert(make_pair(1,10));//插入數據(這種方式不用寫數據類型)m1.insert(make_pair(1,20));//不允許插入重復的key值(保留先插入的) cout<<"容器是否為空:"<<m1.empty()<<endl;cout<<"容器元素個數:"<<m1.size()<<endl;cout<<"容器中有幾個key為1的值:" <<m1.count(1)<<endl;map<int,int>::iterator pos = m1.find(2);//查找有沒有key為2的元素,返回迭代器if(pos!=m1.end()){cout<<"找到了"<<endl;} m1.swap(m2);//交換兩個容器的元素 cout<<m2[1]<<endl;//利用key訪問value值 m2.erase(m2.begin());//刪除迭代器指定元素m2.erase(2);//根據指定的key值刪除 m2.erase(m2.begin(),m2.end());//根據指定區間刪除m2.clear();//清空容器 return 0; }

二、枚舉

三、排序

試題 歷屆試題 字串排序

問題描述

小藍最近學習了一些排序算法,其中冒泡排序讓他印象深刻。 在冒泡排序中,每次只能交換相鄰的兩個元素。 小藍發現,如果對一個字符串中的字符排序,只允許交換相鄰的兩個字符,則在所有可能的排序方案中,冒泡排序的總交換次數是最少的。 例如,對于字符串 lan 排序,只需要 1次交換。對于字符串 qiao 排序,總共需要4次交換。 小藍的幸運數字是V,他想找到一個只包含小寫英文字母的字符串,對這個串中的字符進行冒泡排序,正好需要V次交換。請幫助小藍找一個這樣的字符串。如果可能找到多個,請告訴小藍最短的那個。如果最短的仍然有多個,請告訴小藍字典序最小的那個。請注意字符串中可以包含相同的字符。
輸入格式
輸入一行包含一個整數 ,為小藍的幸運數字。
輸出格式
輸出一個字符串,為所求的答案。
樣例輸入
4
樣例輸出
bbaa

四、搜索

一個很贊的BFS和DFS講解

1.BFS(廣度優先——隊列)

引子:

試題1 歷屆試題 九宮重排

問題描述
  如下面第一個圖的九宮格中,放著 1~8 的數字卡片,還有一個格子空著。與空格子相鄰的格子中的卡片可以移動到空格中。經過若干次移動,可以形成第二個圖所示的局面。

我們把第一個圖的局面記為:12345678.把第二個圖的局面記為:123.46758 顯然是按從上到下,從左到右的順序記錄數字,空格記為句點。本題目的任務是已知九宮的初態和終態,求最少經過多少步的移動可以到達。如果無論多少步都無法到達,則輸出-1。
輸入格式
  輸入第一行包含九宮的初態,第二行包含九宮的終態。
輸出格式
  輸出最少的步數,如果不存在方案,則輸出-1。
樣例輸入
12345678.
123.46758
樣例輸出 3
樣例輸入
13524678.
46758123.
樣例輸出 22

代碼梳理

1.將九宮格的初始狀態和目標狀態以二維數組的形式存儲,并標記初始空白格的位置 2.從初始狀態的空白格開始廣度優先遍歷 ->終止條件,達到目標狀態,輸出步驟/不存在方案 輸出-1 ->搜索:將當前狀態入隊,從隊頭開始,把空白格向四個方向挪動,如果可以挪動,判斷是否滿足目標九宮格,不滿足再把當前狀態入隊。當無法再挪動時,在從隊頭尋找新的狀態,直到隊空。 3.剪枝:其中在bfs時,如果遇到之前已經出現的狀態就不需要再遍歷了。

實現代碼

#include<iostream> #include<bits/stdc++.h> #include<map> #include<queue> using namespace std; char start[4][4]; char goal[4][4]; int df[4][2]={{-1,0},{1,0},{0,-1},{0,1}}; map<string,int> vis; struct Node{//結點結構體,存儲當前坐標,步驟,九宮格狀態 int x,y;long long step;char Map[4][4]; }; bool check_g(Node a){for(int i=1;i<=3;i++){for(int j=1;j<=3;j++){if(a.Map[i][j]!=goal[i][j])return false;//如果有一個位置不符合就返回false }}return true;//全部符合就返回true } bool check_cf(Node a){//判斷剪枝 string s="";for(int i=1;i<=3;i++){for(int j=1;j<=3;j++){s+=a.Map[i][j];}}if(vis[s]>0)return false;vis[s]++;return true; } int bfs(int x1,int y1){//傳入空白格的標記坐標 Node cur,next;//創立兩個結點 (當前和下一個) cur.x=x1;// 傳入當前空白格的坐標 cur.y=y1;cur.step=0;//初始化步驟數 for(int i=1;i<=3;i++){for(int j=1;j<=3;j++){cur.Map[i][j]=start[i][j];//對當前九宮格初始化 }}queue<Node> Q;//創建一個隊列 Q.push(cur);//將當前結點傳入隊列 if(check_g(cur)){//檢查是否已經轉化成目標九宮格 return cur.step;//已經是目標九宮格返回所需要的步驟 }while(!Q.empty()){//如果隊列不為空 cur=Q.front();//取出隊頭元素 Q.pop();//出隊 for(int i=0;i<4;i++){next.x=cur.x+df[i][0];//分別將空白格向四個方向移動 next.y=cur.y+df[i][1];for(int i1=1;i1<=3;i1++){for(int j=1;j<=3;j++){next.Map[i1][j]=cur.Map[i1][j];//存入下一個九宮格的狀態 }}next.step=cur.step+1;//挪動的步驟+1 if(next.x>=1&&next.x<=3&&next.y>=1&&next.y<=3){//如果在邊界內 swap(next.Map[next.x][next.y],next.Map[cur.x][cur.y]);//移動空白格 if(check_cf(next)){//檢查是否重復 if(check_g(next)){//檢查是否滿足需求 return next.step;}Q.push(next);//把當前結點入隊 }} }}return -1; } int main(){int x1,y1;//空白格的位置 for(int i=1;i<=3;i++){for(int j=1;j<=3;j++){cin>>start[i][j];//輸入起始九宮格狀態 if(start[i][j]=='.'){x1=i; //遇到 。標記位置 y1=j;}}}for(int i=1;i<=3;i++){for(int j=1;j<=3;j++){cin>>goal[i][j];//輸入目標九宮格的狀態 }}cout<<bfs(x1,y1)<<endl;//bfs尋找最小步驟 return 0; }

2.DFS(深度優先——棧)

引子:棋盤中的棋子擺放方法有幾種

試題1 歷屆試題 大臣的旅費

問題描述
很久以前,T王國空前繁榮。為了更好地管理國家,王國修建了大量的快速路,用于連接首都和王國內的各大城市。為節省經費,T國的大臣們經過思考,制定了一套優秀的修建方案,使得任何一個大城市都能從首都直接或者通過其他大城市間接到達。同時,如果不重復經過大城市,從首都到達每個大城市的方案都是唯一的。J是T國重要大臣,他巡查于各大城市之間,體察民情。所以,從一個城市馬不停蹄地到另一個城市成了J最常做的事情。他有一個錢袋,用于存放往來城市間的路費。聰明的J發現,如果不在某個城市停下來修整,在連續行進過程中,他所花的路費與他已走過的距離有關,在走第x千米到第x+1千米這一千米中(x是整數),他花費的路費是x+10這么多。也就是說走1千米花費11,走2千米要花費23。J大臣想知道:他從某一個城市出發,中間不休息,到達另一個城市,所有可能花費的路費中最多是多少呢?
輸入格式
輸入的第一行包含一個整數n,表示包括首都在內的T王國的城市數城市從1開始依次編號,1號城市為首都。接下來n-1行,描述T國的高速路(T國的高速路一定是n-1條)每行三個整數Pi, Qi, Di,表示城市Pi和城市Qi之間有一條高速路,長度為Di千米。
輸出格式
輸出一個整數,表示大臣J最多花費的路費是多少。

#include<iostream> #include<vector> #include<bits/stdc++.h> using namespace std; struct road{int d,l; }; vector<road> G[10000]; int visit[10000]; int totallen,maxlen,start; void dfs(int s){if(maxlen<totallen){maxlen=totallen;start=s;}for(int i=0;i<G[s].size();i++){road k=G[s][i];if(!visit[k.d]&&k.l){visit[k.d]=1;totallen+=k.l;dfs(k.d);visit[k.d]=0;totallen-=k.l;}}return; } int main(){int n,a,s;cin>>n;road r;for(int i=0;i<n-1;i++){cin>>s>>r.d>>r.l;G[s].push_back(r);a=r.d;r.d=s;G[a].push_back(r); }memset(visit,0,sizeof(visit));totallen=0;visit[1]=1;dfs(1);memset(visit,0,sizeof(visit));totallen=0;maxlen=-1;visit[start]=1;dfs(start);cout<<((11+10+maxlen)*maxlen)/2<<endl;return 0; }

3.回溯算法總結

一個很好的回溯算法總結

題型:組合,切割,子集,排列,棋盤

回溯模板

void backtracking(參數) {if (終止條件) {存放結果;return;}for (選擇:本層集合中元素(樹中節點孩子的數量就是集合的大小)) {處理節點;backtracking(路徑,選擇列表); // 遞歸回溯,撤銷處理結果} }

(1)組合

#include<bits/stdc++.h> #include<vector> using namespace std; vector<int> path; vector< vector<int> > result;//這里要注意<>中的空格不然會當>>報錯 void backtracking(int n,int k,int starIndex){if(path.size()==k){result.push_back(path);for(int i=0;i<path.size();i++){cout<<path[i];}cout<<endl;return;}for(int i=starIndex;i<=n-(k-path.size())+1;i++){//優化剪枝path.push_back(i);backtracking(n,k,i+1);path.pop_back();} } int main(){int n,k;//返回 1 ... n 中所有可能的 k 個數的組合cin>>n>>k;backtracking(n,k,1); return 0; }

(2)組合總和

#include<bits/stdc++.h> #include<vector> using namespace std; vector<int> path; vector< vector<int> > result; int targetsum; void backtracking(int n,int k,int sum,int starIndex){if(sum>targetsum){return;}if(path.size()==k){if(sum==targetsum){result.push_back(path);for(int i=0;i<path.size();i++){cout<<path[i];}cout<<endl; } return;}for(int i=starIndex;i<=n;i++){sum+=i;path.push_back(i);backtracking(n,k,sum,i+1);sum-=i; path.pop_back();} } int main(){int n,k;//返回 1 ... n 中所有可能的 k 個數的組合使其達到目標值 cin>>n>>k>>targetsum;backtracking(n,k,0,1);cout<<"總共有:"<<result.size()<<"取法"<<endl; return 0; }

(3)分割回文串

#include<bits/stdc++.h> #include<vector> using namespace std; vector<string> path; vector< vector<string> > result; bool isPalindrome(string s,int start,int end){for(int i=start,j=end;i<j;i++,j--){if(s[i]!=s[j]){return false;}}return true; } void backtracking(string s,int startIndex){if(startIndex>=s.size()){result.push_back(path);return;}for(int i=startIndex;i<=s.size();i++){if(isPalindrome(s,startIndex,i)){string str=s.substr(startIndex,i-startIndex+1);//獲取分割子串 path.push_back(str);}else{continue;}backtracking(s,i+1);path.pop_back();} } int main(){string s;cin>>s;backtracking(s,0);cout<<"總共有:"<<result.size()<<"取法"<<endl; return 0; }

(4)求子集

#include<bits/stdc++.h> #include<vector> using namespace std; vector<int> path; vector< vector<int> > result; vector<int> nums; void backtracking(vector<int> nums,int startIndex){result.push_back(path);for(int i=0;i<path.size();i++){cout<<path[i];}cout<<endl;if(startIndex>=nums.size()){return;}for(int i=startIndex;i<nums.size();i++){path.push_back(nums[i]);backtracking(nums,i+1);path.pop_back();} } int main(){int n,num;cin>>n;//輸入要求子集的集合 for(int i=1;i<=n;i++){cin>>num;nums.push_back(num);}backtracking(nums,0);cout<<"總共有:"<<result.size()<<"子集"<<endl; return 0; }

五、計數

六、貪心

七、動態規劃(本質遞歸)

引子:Fibonacci sequence
利用遞推公式:Fib(n+2) = Fib(n+1) + Fib(n),Fib(1) = Fib(2) = 1

利用遞歸的時間復雜度O(2^n),想象成一棵二叉樹,每次計算一個新的Fib(n)就要展開一次分支,效率很低。
但是如果把得出結果的Fib(n)、Fib(n-1)保存,Fib(n+1)用到的時候直接調用,是不是就把效率提高了。這就是動態規劃的思想。下面利用動態規劃解決一下Fibonacci sequence問題。

#include <iostream> #define MAX 10000 using namespace std; int Fib(int n){int F[MAX];//用數組存儲結果F[1]=F[2]=1;for(int i=3;i<=n;i++)F[i]=F[i-1]+F[i-2];return F[n];//直接調用 } int main() {cout<<Fib(6)<<endl;return 0; }

使用情形
1、選擇/不選擇,求最優解(2維dp)以下試題按照難以程度升序排列

試題1 算法提高 01背包

問題描述
  給定N個物品,每個物品有一個重量W和一個價值V.你有一個能裝M重量的背包.問怎么裝使得所裝價值最大.每個物品只有一個.
輸入格式
  輸入的第一行包含兩個整數n, m,分別表示物品的個數和背包能裝重量。
  以后N行每行兩個數Wi和Vi,表示物品的重量和價值
輸出格式
  輸出1行,包含一個整數,表示最大價值。
樣例輸入
3 5
2 3
3 5
4 7
樣例輸出
8
數據規模和約定
1<=N<=200,M<=5000.

#include<bits/stdc++.h> using namespace std; int W[5004]; int Vi[5004]; int dp[5004][5004];//動態規劃 int main(){int n,m;cin>>n>>m;for(int i=1;i<=n;i++){cin>>W[i]>>Vi[i];}for(int i=1;i<=n;i++){for(int j=1;j<=m;j++){dp[i][j]=dp[i-1][j];if(j>=W[i]){dp[i][j]=max(dp[i][j],dp[i-1][j-W[i]]+Vi[i]);// }}}cout<<dp[n][m];//最大價值 return 0; }

試題2 試題 算法提高 秘密行動

問題描述
  小D接到一項任務,要求他爬到一座n層大廈的頂端與神秘人物會面。這座大廈有一個神奇的特點,每層的高度都不一樣,同時,小D也擁有一項特殊能力,可以一次向上跳躍一層或兩層,但是這項能力無法連續使用。已知向上1高度消耗的時間為1,跳躍不消耗時間。由于事態緊急,小D想知道他最少需要多少時間到達頂層。
輸入格式
  第一行包含一個整數n,代表樓的高度。
  接下來n行每行一個整數ai,代表i層的樓層高度(ai <= 100)。
輸出格式
  輸出1行,包含一個整數,表示所需的最短時間。
樣例輸入
5
3
5
1
8
4
樣例輸出
1
數據規模和約定
  對20%的數據,n<=10
  對40%的數據,n<=100
  對60%的數據,n<=5000
  對100%的數據,n<=10000

#include<bits/stdc++.h> using namespace std; int main(){int n;cin>>n;int ai[10005];for(int i=1;i<=n;i++){cin>>ai[i];}int dp[10005][2];//動態規劃二維dp[每層樓][每層樓的選擇0爬,1跳] memset(dp,0,sizeof(dp));dp[1][0]=ai[1];//初始化,第一層選擇爬的情況dp[1][1]=0;//第一層選擇跳的情況for(int i=2;i<=n;i++){dp[i][0]=min(dp[i-1][0],dp[i-1][1])+ai[i];//如果選擇爬的話,那么之前一層可以是爬,也可以是跳上來的dp[i][1]=min(dp[i-1][0],dp[i-2][0]);//如果是使用超能力,那么之前的一層/兩層必須是爬上來的 } cout<<min(dp[n][0],dp[n][1])<<endl;//選擇最終耗時最短的方法 return 0; }

試題3 算法提高 第二點五個不高興的小明

問題描述   有一條長為n的走廊,小明站在走廊的一端,每次可以跳過不超過p格,每格都有一個權值wi。   小明要從一端跳到另一端,不能回跳,正好跳t次,請問他跳過的方格的權值和最大是多少?
輸入格式   輸入的第一行包含兩個整數n, p, t,表示走廊的長度,小明每次跳躍的最長距離和小明跳的次數。   接下來n個整數,表示走廊每個位置的權值。
輸出格式   輸出一個整數。表示小明跳過的方格的權值和的最大值。
樣例輸入 8 5 3 3 4 -1 -100 1 8 7 6
樣例輸出 12
數據規模和約定   1<=n, p, t<=1000, -1000<=wi<=1000。

#include<bits/stdc++.h> using namespace std; const long long int inf=0x3f3f3f; int main(){long long int n,p,t;cin>>n>>p>>t;long long int dp[1005][1005]; //當前格,當前跳的最大權值和long long int wi[1005];for(int i=1;i<=n;i++){//輸入每一格距離的權值 cin>>wi[i];} if(n>p*t){n=p*t;//劃定距離,使其在跳躍能力范圍內 } for(int i=n;i>=n-p&&i>=0;i--){//動態規劃的初始化,我們從最后開始,定義最后一步。 dp[i][1]=wi[i];//最后一格的最后一跳 } for(int i=n;i>=0;i--){for(int j=2;j<=t;j++){dp[i][j]=-inf;for(int k=1;k<=p&&i+k<=n;k++){dp[i][j]=max(dp[i+k][j-1],dp[i][j]);}if(dp[i][j]!=-inf){dp[i][j]+=wi[i];//如果找出步數內的最大值,那么加上自身的權值 }}} cout<<dp[0][t]<<endl;return 0; }

試題4 算法提高 和諧宿舍2

問題描述
  我的某室友學過素描,墻上有n張他的作品。這些作品都是寬度為1,高度不定的矩形,從左到右排成一排,且底邊在同一水平線上。宿舍評比就要來了,為了及格,我們決定買不多于m塊的矩形木板,把這些作品和諧掉。要求木板也從左到右排成一排,且底邊與作品的底邊在同一水平線上。在能夠把所有作品和諧掉的前提下,我們希望這些木板的面積和最小,問最小面積和。
  
輸入格式
  第一行兩個數n和m,表示作品數和木板數;
  第二行n個數Hi,表示從左到右第i個作品的高度。
輸出格式
  一行一個數ans,表示答案。
樣例輸入
5 2
4 2 3 5 4
樣例輸出
22
數據規模和約定
  對于30%的數據:1<=n,m<=10;
  對于100%的數據:1<=n,m<=100,1<=Hi<=10000。

#include<bits/stdc++.h> #define INF 0x3f3f3f3f using namespace std; int main(){int h[105];int hmax[105][105];int dp[105][105];int n,m;cin>>n>>m;for(int i=1;i<=n;i++){cin>>h[i];} for(int i=1;i<=n;i++){ for(int j=i;j<=n;j++){hmax[i][j]=max(hmax[i][j-1],h[j]);}}memset(dp,INF,sizeof(dp));for(int i=1;i<=n;i++){ dp[i][1]=i*hmax[1][i];for(int j=2;j<=m;j++){for(int k=1;k<=i-j+1;k++){dp[i][j]=min(dp[i][j],dp[i-k][j-1]+k*hmax[i-k+1][i]);}}}cout<<dp[n][m]<<endl;return 0; }

八、圖論

dfs:

  • tarjan算法
  • lca算法
  • 九、數論

    十、博弈論

    十一、概率論

    十二、計算幾何

    十三、字符串算法

    KMP(主要應用在字符串匹配上)

    一個很好的KMP總結

    前綴:不包含尾字母的所有子串
    后綴:不包含首字母的所有子串
    前綴表:相等前后綴的記錄

    匹配模型

    構建前綴表

    void getNext_1(int *next,string s){int j=0;next[j]=0;for(int i=1;i<s.size();i++){while(j>0&&s[i]!=s[j]){j=next[j-1];}if(s[i]==s[j]){j++;}next[i]=j;} }

    主函數調用

    int main(){string s;//需要匹配的字符string s1;//被匹配的字符 cin>>s>>s1; int next[s.size()];getNext(next,s);int j=0;for(int i=0;i<s1.size();i++){while(j>0&&s1[i]!=s[j]){j=next[j-1];}if(s1[i]==s[j]){j++;}if(j==s.size()){cout<<s1<<"可以匹配"<<endl;break;}}return 0; }

    試題1:算法提高 字符串匹配

    問題描述
      給出一個字符串和多行文字,在這些文字中找到字符串出現的那些行。你的程序還需支持大小寫敏感選項:當選項打開時,表示同一個字母的大寫和小寫看作不同的字符;當選項關閉時,表示同一個字母的大寫和小寫看作相同的字符。
    輸入格式   
      輸入的第一行包含一個字符串S,由大小寫英文字母組成。
       第二行包含一個數字,表示大小寫敏感的選項,當數字為0時表示大小寫不敏感,當數字為1時表示大小寫敏感。
      第三行包含一個整數n,表示給出的文字的行數。   
      接下來n行,每行包含一個字符串,字符串由大小寫英文字母組成,不含空格和其他字符。
    輸出格式   
      輸出多行,每行包含一個字符串,按出現的順序依次給出那些包含了字符串S的行。
    樣例輸入
    Hello 1 5 HelloWorld
    HiHiHelloHiHi
    GrepIsAGreatTool HELLO
    HELLOisNOTHello
    樣例輸出
    HelloWorld
    HiHiHelloHiHi
    HELLOisNOTHello
    樣例說明
      在上面的樣例中,第四個字符串雖然也是Hello,但是大小寫不正確。如果將輸入的第二行改為0,則第四個字符串應該輸出。 評測用例規模與約定
      1<=n<=100,每個字符串的長度不超過100。

    #include<bits/stdc++.h> using namespace std; string s1[104]; string s; void getNext_0(int *next,string s){int j=0;next[j]=0;for(int i=1;i<s.size();i++){char c1,c2;c1=s[i]-'A'+'a';c2=s[i]-'a'+'A';while(j>0&&c1!=s[j]&&c2!=s[j]&&s[i]!=s[j]){j=next[j-1];}if(s[i]==s[j]||c1==s[j]||c2==s[j]){j++;}next[i]=j;} } void getNext_1(int *next,string s){int j=0;next[j]=0;for(int i=1;i<s.size();i++){while(j>0&&s[i]!=s[j]){j=next[j-1];}if(s[i]==s[j]){j++;}next[i]=j;} } int main(){int num,n;cin>>s>>n>>num;for(int i=0;i<num;i++){cin>>s1[i]; }if(s.size()==0){return 0;}int next[s.size()];for(int k=0;k<num;k++){string p=s1[k];if(p.size()<s.size()){continue;}if(n==0){//大小寫不敏感 getNext_0(next,s);int j=0;for(int i=0;i<p.size();i++){char c1,c2;c1=p[i]-'A'+'a';c2=p[i]-'a'+'A';while(j>0&&p[i]!=s[j]&&c1!=s[j]&&c2!=s[j]){j=next[j-1];}if(p[i]==s[j]||c1==s[j]||c2==s[j]){j++;}if(j==s.size()){cout<<p<<endl;break;//這里加break很重要不然如果一個字符串中有其他匹配的就會一直輸出。}}}if(n==1){//大小寫敏感 getNext_1(next,s);int j=0;for(int i=0;i<p.size();i++){while(j>0&&p[i]!=s[j]){j=next[j-1];}if(p[i]==s[j]){j++;}if(j==s.size()){cout<<p<<endl;break;}}}}return 0; }

    十四、數組

    十五、對象/結構

    十六、字符串

    十七、隊列

    試題 算法提高 隊列操作

    【問題描述】
      隊列操作題。根據輸入的操作命令,操作隊列(1)入隊、(2)出隊并輸出、(3)計算隊中元素個數并輸出。
    輸入格式
      第一行一個數字N。
      下面N行,每行第一個數字為操作命令(1)入隊、(2)出隊并輸出、(3)計算隊中元素個數并輸出。
    輸出格式
      若干行每行顯示一個2或3命令的輸出結果。注意:2.出隊命令可能會出現空隊出隊(下溢),請輸出“no”,并退出。
    樣例輸入
    7
    1 19
    1 56
    2
    3
    2
    3
    2
    樣例輸出
    19
    1
    56
    0
    no
    數據規模和約定
      1<=N<=50

    【思路】這里用到了queue(隊列的STL容器)

    定義一個queue的變量 queue<Type> Q 查看是否為空范例 Q.empty() 是的話返回1,不是返回0; 從已有元素后面增加元素 Q.push() 輸出現有元素的個數 Q.size() 顯示第一個元素 Q.front() 顯示最后一個元素 Q.back() 清除第一個元素 Q.pop()

    【注意】這里有個很頂的地方就是輸出0后退出,就是漏了這個條件一直不能滿分,這種編程題一定要看全!!!!

    #include<bits/stdc++.h> #include<queue> using namespace std; queue<string> q; int main(){stringstream ss;string s1;int N,op;string num;int k=0;cin>>N;string a[N];for(int i=0;i<N;i++){cin>>op;if(op==1){cin>>num;q.push(num);}if(op==2){if(!q.empty()){a[k++]=q.front();q.pop();}else{a[k++]="no";//請輸出“no”,并退出。break;}}if(op==3){ss<<q.size();ss>>s1; a[k++]=s1;ss.clear();}}for(int i=0;i<k;i++){cout<<a[i]<<endl;}return 0; }

    十八、棧

    試題 算法訓練 棧的研究

    [問題描述]
    寧寧考慮的是這樣一個問題:一個操作數序列,從1,2,一直到n(圖示為1到3的情況),棧A的深度大于n。
      現在可以進行兩種操作,
      1.將一個數,從操作數序列的頭端移到棧的頭端(對應數據結構棧的push操作)
      2. 將一個數,從棧的頭端移到輸出序列的尾端(對應數據結構棧的pop操作)
      使用這兩種操作,由一個操作數序列就可以得到一系列的輸出序列,下圖所示為由
      1 2 3
      生成序列
      2 3 1
      的過程。
      
    (原始狀態如上圖所示)
    你的程序將對給定的n,計算并輸出由操作數序列1,2,…,n經過操作可能得到的輸出序列的總數。
    輸入格式
      輸入文件只含一個整數n(1≤n≤18)
    輸出格式
      輸出文件只有一行,即可能輸出序列的總數目
    樣例輸入
    3
    樣例輸出
    5

    【思路】這里我用到了卡特蘭數,有興趣的話你也可以用數學歸納推一下。
    (n個不同的元素進棧,出棧不同序列個數有(1/1+n)*C(n,2n))

    #include<bits/stdc++.h> using namespace std; int main(){int n;long long count;cin>>n;long long a=1;//分子long long b=n+1;//分母 long long temp;for(int i=0;i<n;i++){temp=2*n-i;a*=temp;temp=n-i;b*=temp;while(a%2==0&&b%2==0){//因為數字很大,只能時間換空間,除二收益很大,得不出答案再除以5,【7 9 11……以此類推】a/=2;b/=2;}while(a%3==0&&b%3==0){a/=3;b/=3;}}count=a/b;cout<<count<<endl;return 0; }

    十九、圖

    二十、堆

    二十一、平衡樹/線段樹

    二十二、復雜數據結構

    二十三、嵌套數據結構

    第八屆藍橋杯大賽軟件類決賽

    試題A:36進制

    [問題描述]
    對于16進制,我們使用字母A-F來表示10及以上的數字。如法炮制,一直用到字母Z,就可以表示36進制。36進制中,A表示10,Z表示35,AA表示370你能算出
    MANY 表示的數字用10進制表示是多少嗎?
    [答案提交]
    1040254

    #include<bits/stdc++.h> using namespace std; int main(){int num;num=('m'-'a'+10)*pow(36,3)+('a'-'a'+10)*pow(36,2)+('n'-'a'+10)*36+('y'-'a'+10);cout<<num<<endl;return 0; }

    試題B:磁磚樣式

    [問題描述] 小明家的一面裝飾墻原來是 310 的小方格?,F在手頭有一批剛好能蓋住2個小方格的長方形瓷磚。瓷磚只有兩種顏色:黃色和橙色。小明想知道,對于這么簡陋的原料,可以貼出多少種不同的花樣來。小明有個小小的強迫癥:忍受不了任何22的小格子是同一種顏色。(瓷磚不能切割,不能重疊,也不能只鋪一部分。另外,只考慮組合圖案,請忽略瓷磚的拼縫)顯然,對于 23 個小格子來說,口算都可以知道:一共10種貼法,如【p1.png所示】但對于 310 的格子呢?肯定是個不小的數目,請你利用計算機的威力算出該數字。

    [答案提交]

    在這里插入代碼片

    第九屆藍橋杯大賽軟件類決賽

    試題A:換零鈔

    [問題描述]
    x星球的鈔票的面額只有:100元,5元,2元,1元,共4種。 小明去x星旅游,他手里只有2張100元的x星幣,太不方便,恰好路過x星銀行就去換零錢。小明有點強迫癥,他堅持要求200元換出的零鈔中2元的張數剛好是1元的張數的10倍, 剩下的當然都是5元面額的。銀行的工作人員有點為難,你能幫助算出:在滿足小明要求的前提下,最少要換給他多少張鈔票嗎? (5元,2元,1元面額的必須都有,不能是0)
    [答案提交]
    74

    #include<bits/stdc++.h> using namespace std; int main(){for(int i=1;i<10;i++){int num,sum;num=200-21*i;num=num/5;if(num*5+21*i==200){sum=11*i+num;cout<<sum<<endl;}}return 0; }

    試題B:激光樣式

    [問題描述]
    x星球的盛大節日為增加氣氛,用30臺機光器一字排開,向太空中打出光柱。安裝調試的時候才發現,不知什么原因,相鄰的兩臺激光器不能同時打開!國王很想知道,在目前這種bug存在的情況下,一共能打出多少種激光效果?顯然,如果只有3臺機器,一共可以成5種樣式,即:
    全都關上(sorry, 此時無聲勝有聲,這也算一種) 開一臺,共3種 開兩臺,只1種, 30臺就不好算了,國王只好請你幫忙了。要求提交一個整數,表示30臺激光器能形成的樣式種數。
    [答案提交]
    2178309

    #include<bits/stdc++.h> using namespace std; int main(){int dp[30][2];//30盞燈每盞都可以有兩種狀態選擇 dp[0][0]=1;dp[0][1]=1;//為第一盞燈初始化for(int i=1;i<30;i++){dp[i][0]=dp[i-1][0]+dp[i-1][1];//如果當前燈是滅的它前一盞燈可以亮也可以不亮 dp[i][1]=dp[i-1][0];//當前燈如果要是亮的,前一盞燈就得是滅的 } cout<<dp[29][0]+dp[29][1]<<endl; return 0; }

    第十屆藍橋杯大賽軟件類決賽(難度分水嶺)

    試題A:平方序列

    [問題描述] 小明想找到兩個正整數X和Y,滿足 ●2019<X< Y; ●2019, x2, Y2組成等差數列。 請你求出在所有可能的解中,X+ Y的最小值是多少?
    [答案提交]
    7020

    #include<bits/stdc++.h> using namespace std; int main(){bool flag=true;int x=2020;int num1,num2;while(flag){num1=2*x*x-2019*2019;num2=sqrt(num1);if(num2*num2==num1){cout<<num2+x<<endl;flag=false;}x++;} }

    試題B:質數拆分

    [問題描述] 將2019拆分為若千個兩兩不同的質數之和,一共有多少種不同的方法?
    注意交換順序視為同一種方法,例如2+ 2017= 2019與2017 +2= 2019視為同一種方法。
    [答案提交]
    55965365465060

    解析:
    這是一個jave關于這道題的解析,里面的一張圖示我覺得超贊就摘錄了

    #include<bits/stdc++.h> #include<vector> using namespace std;//找出2019中(2-2019每個數字中有幾個質數,選擇或者不選擇) bool fun(int n){for(int i=2;i<=sqrt(n);i++){if(n%i==0){return false;}}return true; } int main(){vector<int> V;long long int dp[3000];for(int i=2;i<=2019;i++){if(fun(i)){V.push_back(i);}}memset(dp,0,sizeof(dp));dp[0]=1;for(int i=0;i<V.size();i++){for(int j=2019;j>=V[i];j--){dp[j]=dp[j]+dp[j-V[i]];}}cout<<dp[2019]<<endl;return 0; }

    第十一屆藍橋杯大賽軟件類決賽

    試題A:美麗的2

    [問題描述] 小藍特別喜歡2,今年是公元2020年,他特別高興。他很好奇,在公元1年到公元2020年(包含)中,有多少個年份的數位中 包含數字2?
    [答案提交]
    563

    #include<bits/stdc++.h> using namespace std; int main(){int q,b,s,g;int ans=0;for(int i=1;i<=2020;i++){q=i/1000;b=i%1000/100;s=i%100/10;g=i%10;if(q==2||b==2||s==2||g==2){ans++;}}cout<<ans<<endl;return 0; }

    試題B:擴散(BFS)

    [問題描述] 小藍在一張無限大的特殊畫布上作畫。 這張畫布可以看成一個方格圖,每個格子可以用一個二維的整數坐標表示。小藍在畫布上首先點了一下幾個點: (0,0), (2020, 11), (11, 14), (2000, 2000)。只有這幾個格子上有黑色,其它位置都是白色的。 每過一分鐘,黑色就會擴散一點。具體的,如果一個格子里面是黑色,它就會擴散到上、下、左、右四個相鄰的格子中,使得這四個格子也變成黑色 (如果原來就是黑色,則還是黑色)。請問,經過2020分鐘后,畫布上有多少個格子是黑色的。
    [答案提交]
    20312088

    #include<iostream> #include<cstring> #include<queue> using namespace std; int m[6100][6100]; int ans; const int a=2021; int fx[4][2]={{1,0},{0,1},{0,-1},{-1,0}}; struct node{int x,y;int time; }; void bfs(){queue<node> Q;m[0+a][0+a]=1;m[2020+a][11+a]=1;m[11+a][14+a]=1;m[2000+a][2000+a]=1;node n1,n2,n3,n4;n1.x=0+a;n1.y=0+a;n1.time=0;Q.push(n1);n2.x=2020+a;n2.y=11+a;n2.time=0;Q.push(n2);n3.x=11+a;n3.y=14+a;n3.time=0;Q.push(n3);n4.x=2000+a;n4.y=2000+a;n4.time=0;Q.push(n4);ans=4;node temp,next;while(!Q.empty()){temp=Q.front();Q.pop();if(temp.time==2020){cout<<ans<<endl;return;}for(int i=0;i<4;i++){next.x=temp.x+fx[i][0];next.y=temp.y+fx[i][1];if(!m[next.x][next.y]){ans++;next.time=temp.time+1;m[next.x][next.y]=1;Q.push(next);}}} } int main(){memset(m,0,sizeof(m));bfs();return 0; }

    試題C:階乘約數

    [問題描述] 定義階乘n!= 1x2x3x…Xn。
    請問100! (100 的階乘)有多少個正約數。
    [答案提交]
    39001250856960000

    #include<bits/stdc++.h> using namespace std; int num_1[105]; int main(){long long int sum=1;memset(num_1,0,sizeof(num_1));for(int i=2;i<=100;i++){int num=i;for(int j=2;j<=sqrt(i);j++){while(num%j==0){num_1[j]++;num=num/j;}}if(num>1){num_1[num]++;}}for(int i=2;i<=100;i++){if(num_1[i]!=0){sum=sum*(num_1[i]+1); } }cout<<sum<<endl; }

    試題 D: 本質上升序列(與求子集問題相似)

    【問題描述】
    小藍特別喜歡單調遞增的事物。
    在一個字符串中,如果取出若干個字符,將這些字符按照在字符串中的順序排列后是單調遞增的,則成為這個字符串中的一個單調遞增子序列。
    例如,在字符串 lanqiao 中,如果取出字符 n 和 q,則 nq 組成一個單調遞增子序列。類似的單調遞增子序列還有 lnq、i、ano 等等。
    小藍發現,有些子序列雖然位置不同,但是字符序列是一樣的,例如取第二個字符和最后一個字符可以取到 ao,取最后兩個字符也可以取到 ao。小藍認為他們并沒有本質不同。
    對于一個字符串,小藍想知道,本質不同的遞增子序列有多少個?
    例如,對于字符串 lanqiao,本質不同的遞增子序列有 21 個。它們分別是 l、a、n、q、i、o、ln、an、lq、aq、nq、ai、lo、ao、no、io、lnq、anq、lno、ano、aio。
    請問對于以下字符串(共 200 個小寫英文字母,分四行顯示):
    tocyjkdzcieoiodfpbgcncsrjbhmugdnojjddhllnofawllbhf
    iadgdcdjstemphmnjihecoapdjjrprrqnhgccevdarufmliqij
    gihhfgdcmxvicfauachlifhafpdccfseflcdgjncadfclvfmad
    vrnaaahahndsikzssoywakgnfjjaihtniptwoulxbaeqkqhfwl
    本質不同的遞增子序列有多少個?
    [答案提交]
    3616159

    #include<iostream> #include<vector> #include<string> #include<numeric> using namespace std; string s; int main() {cin>>s;int dp[220];for(int i=0;i<s.size();++i){dp[i] = 1;}for(int i=1;i<s.size();++i){for(int j=0;j<i;++j){if(s[i]==s[j]){dp[i]-=dp[j];}if(s[i]>s[j]){dp[i] += dp[j];}}}cout<<accumulate(dp,dp+s.size(),0);return 0; }

    總結

    以上是生活随笔為你收集整理的蓝桥杯大赛决赛整理合集(B组C/C++)的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。