1. 程式人生 > >藍橋杯常用演算法彙總

藍橋杯常用演算法彙總

<memory.h>或<string.h>

void *memset(void *s, int ch, size_t n);

#include <algorithm>

sort(a,a+n)排序函式,從小到大,a為陣列名字,n為元素個數

sort(vector.begin(),vector.end())排序vector

只要資料型別定義了小於操作符,即可用sort

sort(a,a+n,compare)即可按照自定義順序排列,compare為比較函式,返回值為bool

lower_bound(a,a+n,x)二分查詢,查詢大於或等於x的第一個位置,只能查詢vector<>陣列,返回值為vector<>::iterator指標

    unique(vector1.begin(),vector1.end()),重排元素,使得所有值提前,返回值為重排後最後一個非重複值的後面的值的迭代器,即從返回值到vector1.end()是無意義的值,也是重複值的總數量

reverse(vector1.begin(),vector1.end()),反轉元素順序

next_permutation(p,p+n),求下一個全排列,列舉用

#include <vector>   陣列

定義示例:vector<int> b(5);或者vector<int> a;

賦值:b[0]=1;只有第一種定義可以這樣賦值

函式:

int size(),獲取大小

void resize(int num),改變大小

void push_back(int x),向尾部新增元素

void pop_back(),刪除最後一個元素

void clear(),清空

bool empty(),檢查是否為空

iterator insert(iterator x,y),向vector陣列的x位置插入元素y,x可以為v.begin()+2

iterator erase(iterator x),刪除vector陣列的x位置元素

iterator begin(),返回頭指標

iterator end(),返回尾指標

vector<>::iterator為一個可以指向其元素的指標

#include <set>         集合,其中不含重複元素,且其中元素已從小到大排序,從1開始

定義示例:set<int> a;

函式:

int size(),獲取大小

iterator find(x),若找到x,返回該鍵值迭代器的位置,否則,返回最後一個元素後面一個位置,即s.end()

void clear(),清空

bool empty(),檢查是否為空

iterator insert(y),向set集合插入元素y

iterator erase(iterator x),刪除set集合的值為x的元素,返回值為下一個位置的迭代器

iterator begin(),返回頭指標

iterator end(),返回尾指標

set<>::iterator為一個可以指向其元素的指標

#include <map>       對映,索引

         定義示例:map<string,int> month_name;

賦值:map[“July”]=7;

函式:

iterator find(y),尋找索引值為y的元素,返回指向其的指標

iterator insert(map<string,int>(“July”,7)),向map對映插入元素(“July”,7)

iterator erase(iterator x),刪除map對映的迭代器x的元素

map< string,int>::iterator l_it;;

   l_it=m.find(“July”);

   if(l_it==m.end())

        cout<<"we do not find July"<<endl;

   else  m.erase(l_it);  //delete July;

iterator begin(),返回頭指標

iterator end(),返回尾指標

map<>::iterator為一個可以指向其元素的指標

#include <stack>

定義示例:stack<int> s;

void push(x),將值x壓入棧

void pop(),刪除頂部元素

top(),獲得棧頂元素,但不刪除

bool empty(),檢查是否為空

int size(),獲取大小

#include <queue>

定義示例:queue<int> q;

void push(x),將值x入隊

void pop(),出隊

front(),獲得隊頭元素,但不刪除

bool empty(),檢查是否為空

int size(),獲取大小

#include <string>

string substr(int pos = 0,int n = npos) const;  //返回pos開始的n個字元組成的字串

void swap(string &s2);                                       //交換當前字串與s2的值

string &insert(int p0, const char *s);                //在p0位置插入字串

string &erase(int pos = 0, int n = npos);          //刪除pos開始的n個字元,返回修改後的字串

int find(char c, int pos = 0) const;                     //從pos開始查詢字元c在當前字串的位置

int find(const char *s,int pos = 0) const;         //從pos開始查詢字串s在當前串中的位置

演算法:

快速排序:

void quicksort(int *a,int l,int r){

         if(l>=r)

                  return;

         int temp=a[l];                                    //哨兵

         int i=l,j=r;

         while(i<j){

                  while(i<j){                                   //從右開始往左判斷

                          if(a[j]>=temp){

                                   j--;

                          }

                          else{

                                   a[i++]=a[j];

                                   break;

                          }

                  }

                  while(i<j){                                   //從左開始往右判斷

                          if(a[i]<=temp){

                                   i++;

                          }

                          else{

                                   a[j--]=a[i];

                                   break;

                          }

                  }

         }

         a[i]=temp;                                          //將哨兵放回中間位置

         quicksort(a,l,i-1);                               //左邊排序

         quicksort(a,i+1,r);                             //右邊排序

}

歸併排序:

void mergesort(int *a,int l,int r,int *b){

         if(l>=r)

                  return ;

         int mid=l+r;

         mid/=2;

         mergesort(a,l,mid,b);      //左邊有序

         mergesort(a,mid+1,r,b);  //右邊有序

         int k=l,i=l,j=mid+1;                    //注意k的初值

         while(i<=mid&&j<=r){              //將i-mid和j-r兩組有序序列,歸併在一個有序序列中

                  if(a[i]<=a[j])

                          b[k++]=a[i++];

                  else

                          b[k++]=a[j++];

         }

         while(i<=mid)                            //將i-mid剩餘的數放在最後

                  b[k++]=a[i++];

         while(j<=r)                                 //將j-r剩餘的數放在最後

                  b[k++]=a[j++];

         for(k=l;k<=r;k++)                       //將b陣列中的資料拷貝到原陣列中

                  a[k]=b[k];

}

並查集:

#define N 100

int father[N];

void init() {

    for(int i=0; i<N; i++)

      father[i] = i;

}

// 合併兩個元素所在的集合

void union(int x,int y) {

    x = getfather(x);

    y = getfather(y);

    if(x!= y)

       father[x]=y;

}

// 判斷兩個元素是否屬於同一個集合

bool same(int x,int y) {

    return getfather(x)==getfather(y);

}

// 獲取根結點

int getfather(int x) {

    while(x != father[x])

      x = father[x];

    return x;

}

// 獲取根結點,是上邊函式的改進,壓縮了路徑長度

int getfather(int x) {

    if(x != father[x])

      father[x] = getfather(father[x]); // 路徑壓縮修改的是father陣列

    return father[x];

}

二分查詢:

int erfen(int *a,int l,int r,int v){        //a為待查詢陣列,l為下界下標,r為上界下標,v為目標值

         int mid;

         while(l<=r){

                  mid=l+r;

                  mid/=2;

                  if(a[mid]==v)   return mid;

                  else if(a[mid]>v)      r=mid-1;

                  else  l=mid+1;

         }      

         return -1;

}

01揹包動態規劃:

int f[5000];

int v[201],w[201];

int main(int argc, char** argv) {

         int n=0,m,i,j,mx=0;

         cin>>n>>m;

         for(i=1;i<=n;i++){

                  cin>>w[i]>>v[i];

         }

         for(i=1;i<=n;i++){

                  for(j=m;j>=w[i];j--){

                          f[j]=max(f[j],f[j-w[i]]+v[i]);

                          mx=max(mx,f[j]);

                  }

         }

         cout<<mx;

         return 0;

}

LIS最長上升子序列

int LIS(int *a,int n){

         int *dp=new int[n];         //儲存以i為尾的最長上升子序列長度

         int mx=0,m,i,j;

         dp[0]=1;                            //初值,第一個字元為1

         for(i=1;i<n;i++){

                  m=0;

                  for(j=0;j<i;j++){        //對當前i之前的所有元素的最長上升子序列做判斷

                          if(dp[j]>m&&a[j]<a[i]){

                                   m=dp[j];

                          }

                  }

                  dp[i]=m+1;               //最大m值再加上1

                  mx=max(mx,dp[i]); //同時判斷所有最長上升子序列長度的最大值

         }

         return mx;

}

LCS最長公共子序列

動態規劃法:

void LCS(string str1,string str2)

{

         int x_len = str1.length();

         int y_len = str2.length();

         int arr[50][50] = {{0,0}};

         int i = 0;

         int j = 0;

         //動態規劃二維矩陣

         for(i = 1; i <= x_len; i++)

         {

                  for(j = 1; j <= y_len; j++)

                  {

                          if(str1[i - 1] == str2[j - 1])

                          {

                                   arr[i][j] = arr[i - 1][j - 1] + 1;

                         }

                          else

                          {

                                   if(arr[i][j - 1] >= arr[i - 1][j])

                                   {

                                            arr[i][j] = arr[i][j - 1];

                                   }

                                   else

                                  {

                                            arr[i][j] = arr[i -1][j];

                                   }

                          }

                  }

         }

         //列印最長公共子序列

         stack<char> s;

         for(i = x_len, j = y_len; i >= 1 && j >= 1;)

         {

                  if(str1[i - 1] == str2[j - 1])

                  {

                          s.push(str1[i - 1]);

                          //cout<<str1[i - 1]<<" ";

                          i--;

                          j--;

                  }

                  else

                  {

                          //  if(arr[i][j -1] >= arr[i - 1][j])//列印兩種情況

                          if(arr[i][j -1] > arr[i - 1][j])

                          {

                                   j--;

                          }

                          else

                          {

                                   i--;

                          }

                  }

         }

         while(!s.empty()){

                  cout<<s.top();

                  s.pop();

         }

         cout << endl;

}

遞迴法:(只能求數量)

int LCS(char* x,char *y){

         if(strlen(x)==0)                  return 0;

         if(strlen(y)==0)         return 0;

         if(*x==*y)         return LCS(x+1,y+1)+1;

         return max(LCS(x,y+1),LCS(x+1,y));

}

Dijkstra最短路徑演算法

#define MAX 9999999

#define NUM 6

int edge[NUM][NUM];                     //儲存兩點間距離

int dist[NUM];                                   //儲存到每個點的最短距離

int mark[NUM];                                 //標記是否已選

//n:多少個點  start:起始點   

void Dijkstra(int n,int start){

         int i,j,k=start;

         int min;

         for(i=0;i<n;i++){

                  mark[i]=0;

                  dist[i]=edge[start][i];

         }

         mark[start]=1;

         dist[start]=0;

         for(i=0;i<n;i++){

                  min=MAX;

                  for(j=0;j<n;j++){

                          if(!mark[j]&&dist[j]<min){

                                   min=dist[j];

                                   k=j;

                          }

                  }

                  mark[k]=1;

                  for(j=0;j<n;j++){

                          if(!mark[j]&&dist[j]>dist[k]+edge[k][j]){

                                   dist[j]=dist[k]+edge[k][j];

                          }

                  }

         }

}

Floyd

#define MAX 9999999

#define NUM 6

int edge[NUM][NUM];

int temp[NUM][NUM];

void Floyd(int a[NUM][NUM],int b[NUM][NUM]){

         int i,j,k;

         for(k=0;k<NUM;k++){

                  for(i=0;i<NUM;i++){

                          for(j=0;j<NUM;j++){

                                   if(k==0)

                                            b[i][j]=a[i][j];

相關推薦

藍橋常用演算法彙總

<memory.h>或<string.h>void *memset(void *s, int ch, size_t n);#include <algorithm>sort(a,a+n)排序函式,從小到大,a為陣列名字,n為元素個數sort(

藍橋常用演算法

<memory.h>或<string.h> void *memset(void *s, int ch, size_t n);   #include <algorithm> sort(a,a+n)排序函式,從小到大,a為陣列

機器學習十大常用演算法彙總

1.決策樹     以一個根節點開始,每一個節點提出一個問題,基於feature將資料分為兩類,再子節點上再繼續提問。每個節點上的問題和分類規則是根據已有的訓練資料學習出來的。   決策樹通常有三個步驟:特徵選擇、決策樹的生成、決策樹的修剪。 上圖為一個決策

五大常用演算法彙總

1、五大常用演算法之一:分治演算法:http://www.cnblogs.com/steven_oyj/archive/2010/05/22/1741370.html 2、五大常用演算法之二:動態規劃演算法:http://www.cnblogs.com/steven_oyj/archive/20

藍橋練習-演算法訓練-區間k大數查詢

藍橋杯練習-演算法訓練-區間k大數查詢 題目連結 問題描述 給定一個序列,每次詢問序列中第l個數到第r個數中第K大的數是哪個。 輸入格式 第一行包含一個數n,表示序列長度。 第二行包含n個正整數,表示給定的序列。 第三個包含一個正

藍橋演算法訓練 最小乘積(基本型)

題目:演算法訓練 最小乘積(基本型) 問題描述   給兩組數,各n個。   請調整每組數的排列順序,使得兩組資料相同下標元素對應相乘,然後相加的和最小。要求程式輸出這個最小值。   例如兩組數分別為:1 3  -5和-2 4 1   那麼對應乘積取和的

藍橋演算法訓練 Torry的困惑(基本型)

題目:演算法訓練 Torry的困惑(基本型) 問題描述   Torry從小喜愛數學。一天,老師告訴他,像2、3、5、7……這樣的數叫做質數。Torry突然想到一個問題,前10、100、1000、10000……個質數的乘積是多少呢?他把這個問題告訴老師。老師愣

藍橋_演算法訓練_Torry的困惑(基本型)

這個題目就是求質數的乘積,在加一個模,思路比較簡單,直接上程式碼: 1 #include<iostream> 2 using namespace std; 3 bool isPrim

藍橋演算法訓練 大小寫轉換

題目:演算法訓練 大小寫轉換 問題描述   編寫一個程式,輸入一個字串(長度不超過20),然後把這個字串內的每一個字元進行大小寫變換,即將大寫字母變成小寫,小寫字母變成大寫,然後把這個新的字串輸出。   輸入格式:輸入一個字串,而且這個字串當中只包含英文字

藍橋_演算法訓練_安慰奶牛(用Kruskal、Prim演算法分別實現)

問題描述 Farmer John變得非常懶,他不想再繼續維護供奶牛之間供通行的道路。 道路被用來連線N個牧場,牧場被連續地編號為1到N。每一個牧場都是一個奶牛的家。 FJ計劃除去P條道路中儘可能多的道路,但是還要保持牧場之間 的連通性。 你首先要決定那些

藍橋_演算法訓練_表示式計算

  之前在學習棧的時候老師講過這個問題   思路就是:     1.將表示式(中綴式)轉化成字尾式;     2.進行字尾式的計算。    思路看起來很簡單,但是實際在敲程式碼的時候還是要注意很多問題。

藍橋_演算法訓練_字串統計

其實題目已經給的很清楚了,列舉所有的情況,統計出現次數,找到符合條件的結果。 那麼我們就根據這個提示完成即可: 第一步:列舉所有可能的字串: 1 #include<iostream> 2 #include<string.h> 3 using

藍橋java 演算法訓練 動態陣列使用

  演算法訓練 動態陣列使用  時間限制:1.0s   記憶體限制:512.0MB從鍵盤讀入n個整數,使用動態陣列儲存所讀入的整數,並計算它們的和與平均值分別輸出。要求儘可能使用函式實現程式程式碼。平均值為小數的只保留其整數部分。 樣例輸入: 5 3 4 0 0 2樣例輸出:

藍橋演算法訓練 字串統計

問題描述   給定一個長度為n的字串S,還有一個數字L,統計長度大於等於L的出現次數最多的子串(不同的出現可以相交),如果有多個,輸出最長的,如果仍然有多個,輸出第一次出現最早的。 輸入格式   第一行一個數字L。   第二行是字串S。   L大於0,且不超過S的長度。

藍橋_演算法訓練_操作格子

問題描述 有n個格子,從左到右放成一排,編號為1-n。 共有m次操作,有3種操作型別: 1.修改一個格子的權值, 2.求連續一段格子權值和, 3.求連續一段格子的最大值。 對於每個2、3操作輸出你所求出的結果。 輸入格式 第一行2個整數n,m

林下的碼路(誠接遠端家教輔導:初高中NOI、大學ACM、CCPC、藍橋演算法程式設計類程式設計競賽)

1)區間完全覆蓋問題 問題描述:給定一個長度為m的區間,再給出n條線段的起點和終點(注意這裡是閉區間),求最少使用多少條線段可以將整個區間完全覆蓋 樣例: 區間長度8,可選的覆蓋線段[2,6],[1,4],[3,6],[3,7],[6,8],[2

藍橋演算法訓練)——K好數

演算法描述 問題描述 如果一個自然數N的K進製表示中任意的相鄰的兩位都不是相鄰的數字,那麼我們就說這個數是K好數。求L位K進位制數中K好數的數目。例如K = 4,L = 2的時候,所有K好數為11、13、20、22、30、31、33 共7個。由於這個數目很大

藍橋最短路(java過)&&spfa單源最短路演算法

百度百科上spfa的思路為:動態逼近法:設立一個先進先出的佇列用來儲存待優化的結點,優化時每次取出隊首結點u,並且用u點當前的最短路徑估計值對離開u點所指向的結點v進行鬆弛操作,如果v點的最短路徑估計值有所調整,且v點不在當前的佇列中,就將v點放入隊尾。這樣不斷從佇列中取出結點來進行鬆弛

初級演算法——最大公約數與最小公倍數(藍橋

思路:這裡使用的是輾轉相除法求最大公約數,而  最小公倍數 = 兩數相乘/最大公約數   #include<stdio.h> int main(){ int m,n,a,b,c; printf("input two numbers:"); scanf("%d%d",&a

藍橋 演算法訓練 字母圖形

問題描述 利用字母可以組成一些美麗的圖形,下面給出了一個例子: ABCDEFG BABCDEF CBABCDE DCBABCD EDCBABC 這是一個5行7列的圖形,請找出這個圖形的規律,並輸出一個n行m列的圖形。 輸入格式 輸入一行