【新知識】隊列&bfs【洛谷p1996約瑟夫問題&洛谷p1451求細胞數量】


(是時候為五一培訓准備真正的技術了qwq)

  • part1  隊列(FIFO)
    • 算法簡介:

FIFO:First In First Out(先進先出)

隊列是限定在一端進行插入,另一端進行刪除的特殊線性表。

允許出隊的一頭叫做隊頭(head||front),允許出隊的一端稱為隊尾(rear||tail)所有需要進隊的數據項,只能從隊尾進入,隊列中的數據只能從隊頭離去qwq。


 

今天wz小姐姐講惹一小時滴不知道有什么用滴東西qwq,這里做個筆記吧ヽ(•̀ω•́ )ゝ

1.隊列在c語言中的語法?

No.1頭文件:#include<queue>

No.2統統搞一塊了不管了qwq:

成員函數:

搞到一個神奇的代碼qwq:

#include <queue>
#include <iostream>
using namespace std;
int main()

{ 
       queue<int> myQ; //疑似定義了一個隊列q 
       for(int i=0; i<10; i++) {
            myQ.push(i);//把0~9入隊 
            cout<<"myQ size is: "<<myQ.size()<<endl;//輸出i這個元素入隊之后隊列的長度  
       } 
       for(int i=0; i<myQ.size(); i++) { 
          cout <<"the first:"<< myQ.front()<<endl; //輸出第一個數 
          myQ.pop(); //刪掉第一個數(隊列的長度減小了)
          cout<<"wz is little sister:"<<myQ.size()<<endl; //證明它確實減小了 彩蛋qwq
       } 
       cout<<"this is amazing!"<<endl; 
       return 0;
}

另外還有棧:stack??頭文件的話就是#include<stack>

用法和queue差不多,請自行百度qwq


 

算法標簽:

 

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
using namespace std;
int n,m,p=0,k=1;
int a[200];
int main()
{
    scanf("%d%d",&n,&m);
    int j=n;
    for(int i=1;i<n;i++)a[i]=i+1;
    a[n]=1;
    while(p<n){
        while(k<m){
            printf("%d a w i k o z i %d\n",j,a[j]);
            j=a[j];k++;//為了方便理解,這里加了兩句輸出
            printf("%d a y i k o y i %d\n",j,a[j]);
            puts("-------------------");
        }
        printf("我是答案qwq:%d\n",a[j]);p++;
        a[j]=a[a[j]];k=1;
    }
    return 0;
}
 

 

寫在bfs之前:

關於lower_bound和upper_bound:

這個神奇的東西一直只是見過,咋用完全不會之前,所以今天wz跟我們講(xian)題(che)時候順(zhuang)帶(bi)的講了一下。

寫在語法之前:頭文件:#include<algorithm>某些人疑似叫它阿拉狗日thm

lower_bound和upper_bound都是在sort過以后使用的,(要不然用它沒有意義啊qwq

1.語法:

lower_bound(a+1,a+n+1,r)①//表示在數組a中從a[1]位置到a[n]位置找到第一個大於或等於r的數,返回該數的地址

upper_bound(a+1,a+n+1,r)②//表示在數組a中從a[1]位置到a[n]位置找到第一個大於r的數,返回該數的地址

如何用lower_bound和upper_bound判斷數r在某個部分(用部分吧,用數組不是很嚴謹qwq)是否存在:①==②?不存在:存在(突然想寫三目運算符(大概寫對了吧

求序列中有幾個r:②-①;

求某個數r的下標:lower_bound(a+1,a+n+1,r)-a(no why)

行吧大致補充就end-了


 

  • part2 bfs(廣度優先搜索):
    • 算法描述qwq:Breadth First Search

所謂寬度優先。就是每次都嘗試訪問同一層的節點。 如果同一層都訪問完了,再訪問下一層。

這樣做的結果是,BFS 算法找到的路徑是從起點開始的 最短 合法路徑。換言之,這條路所包含的邊數最小。

在 BFS 結束時,每個節點都是通過從起點到該點的最短路徑訪問的。(from oi-***)

    • 偽代碼:
bfs(s) {
  q = new queue()
  q.push(s)), visited[s] = true
  while (!q.empty()) {
    u = q.pop()
    for each edge(u, v) {
      if (!visited[v]) {
        q.push(v)
        visited[v] = true
      }
    }
  }
}//from oi-**(我沒直接把一本通的打上來已經不錯了qwq 色號#f4f4f4

 

eg:【洛谷p1451求細胞數量】

算法標簽(顯然搜索):

(你猜它來自哪pulapula懶死算了qwq

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<cstdlib>
using namespace std;
char s[110];
int n,m,ans=0;
bool pan[110][110];
int dx[5]={0,1,0,-1,0};
int dy[5]={0,0,1,0,-1};
void bfs(int a,int b){
    int h[1000][3],x,y;
    int t=0,w=1;
    ans++;pan[a][b]=0;
    h[1][1]=a;h[1][2]=b;
    do{
        t++;//丟掉了qwq 
        for(int i=1;i<=4;i++){
            x=h[t][1]+dx[i];
            y=h[t][2]+dy[i];
            if((pan[x][y])&&(x<=n)&&(y<=m)&&(x>0)&&(y>0))
            {
                w++;
                h[w][1]=x;
                h[w][2]=y;
                pan[x][y]=0;
            }
        }
    }while(t<w);
}
int main()
{
    scanf("%d%d",&n,&m);
    for(int i=1;i<=n;i++)
      for(int j=1;j<=m;j++)
        pan[i][j]=1;
    for(int i=1;i<=n;i++){
        scanf("%s",s);
        for(int j=0;j<m;j++){//字符數組從零開始啊喂qwq 
            if(s[j]=='0')pan[i][j+1]=0;//從j零開始的話要加1呢qwq 
        }
    }
    for(int i=1;i<=n;i++)
      for(int j=1;j<=m;j++)
        if(pan[i][j]) bfs(i,j);
    printf("%d",ans);
}

 

 

 

大概可能沒啥了吧qwq???

end-


注意!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系我们删除。



 
粤ICP备14056181号  © 2014-2021 ITdaan.com