雙指針,BFS和圖論(二)

(一)BFSios

1.地牢大師數組

你如今被困在一個三維地牢中,須要找到最快脫離的出路!bash

地牢由若干個單位立方體組成,其中部分不含岩石障礙能夠直接經過,部分包含岩石障礙沒法經過。app

向北,向南,向東,向西,向上或向下移動一個單元距離均須要一分鐘。測試

你不能沿對角線移動,迷宮邊界都是堅硬的岩石,你不能走出邊界範圍。ui

請問,你有可能逃脫嗎?spa

若是能夠,須要多長時間?code

輸入格式

輸入包含多組測試數據。xml

每組數據第一行包含三個整數 L,R,C 分別表示地牢層數,以及每一層地牢的行數和列數。blog

接下來是 L 個 R 行 C 列的字符矩陣,用來表示每一層地牢的具體情況。

每一個字符用來描述一個地牢單元的具體情況。

其中, 充滿岩石障礙的單元格用」#」表示,不含障礙的空單元格用」.」表示,你的起始位置用」S」表示,終點用」E」表示。

每個字符矩陣後面都會包含一個空行。

當輸入一行爲」0 0 0」時,表示輸入終止。

輸出格式

每組數據輸出一個結果,每一個結果佔一行。

若是可以逃脫地牢,則輸出」Escaped in x minute(s).」,其中X爲逃脫所需最短期。

若是不能逃脫地牢,則輸出」Trapped!」。

數據範圍

1L,R,C100

輸入樣例:

3 4 5
S....
.###. .##.. ###.# ##### ##### ##.## ##... ##### ##### #.### ####E 1 3 3 S## #E# ### 0 0 0 

輸出樣例:

Escaped in 11 minute(s). Trapped!

解題思路:一道三維的BFS搜索題,咱們能夠創建三個移動數組:vx,vy,vk,分別表示北,南,東,西,上,下,設置一個三維的map數組來存儲地圖,
設置一個vis數組,用來判斷是否走過以及距離。
代碼:
#include<iostream>
#include<queue>
#include<cstring>
using namespace std;
const int N=110;
int l,r,c;
char map[N][N][N];
int vis[N][N][N];
int vx[]={1,-1,0,0,0,0};
int vy[]={0,0,1,-1,0,0};
int vk[]={0,0,0,0,1,-1};
typedef struct Node
{
    int k,x,y;
};
bool check(int K,int X,int Y)
{
    if(X<0||X>=r||Y<0||Y>=c||K<0||K>=l)
        return false;
    if(map[K][X][Y]=='#')
        return false;
    if(vis[K][X][Y]!=0)
        return false;
    return true;
}
int bfs(Node start)
{
    queue<Node> q;
    memset(vis,0,sizeof(vis));
    q.push(start);
    while(!q.empty())
    {
        Node tem=q.front();
        if(map[tem.k][tem.x][tem.y]=='E')
            return vis[tem.k][tem.x][tem.y];
        q.pop();
        for(int i=0;i<6;i++)
        {
            int X=tem.x+vx[i];
            int Y=tem.y+vy[i];
            int K=tem.k+vk[i];
            if(check(K,X,Y)==false)
                continue;
            vis[K][X][Y]=vis[tem.k][tem.x][tem.y]+1;
            Node t={K,X,Y};
            q.push(t);
        }
    }
    return 0;
}

int main()
{
    int i,j,bx,by,bk,k;
    Node start;
    string ss;
    while(1)
    {
        cin>>l>>r>>c;
        if(l==0&&r==0&&c==0)
            break;
        for(k=0;k<l;k++)
        {
            for(i=0;i<r;i++)
            {
                for(j=0;j<c;j++)
                {
                    cin>>map[k][i][j];
                    if(map[k][i][j]=='S')
                    {
                        bk=k,bx=i,by=j;
                        start={bk,bx,by};
                    }
                }
            }
            getline(cin,ss);
        }
    int ans=bfs(start);
    if(ans)
        cout<<"Escaped in "<<ans<<" minute(s)."<<endl;
    else
        cout<<"Trapped!"<<endl;
    }
    return 0;
}

2.全球變暖

你有一張某海域 N×N 像素的照片,」.」表示海洋、」#」表示陸地,以下所示:

.......
.##.... .##.... ....##. ..####. ...###. ....... 

其中」上下左右」四個方向上連在一塊兒的一片陸地組成一座島嶼,例如上圖就有 2 座島嶼。

因爲全球變暖致使了海面上升,科學家預測將來幾十年,島嶼邊緣一個像素的範圍會被海水淹沒。

具體來講若是一塊陸地像素與海洋相鄰(上下左右四個相鄰像素中有海洋),它就會被淹沒。

例如上圖中的海域將來會變成以下樣子:

.......
.......
.......
.......
....#.. ....... ....... 

請你計算:依照科學家的預測,照片中有多少島嶼會被徹底淹沒。

輸入格式

第一行包含一個整數N。

如下 N 行 N 列,包含一個由字符」#」和」.」構成的 N×N 字符矩陣,表明一張海域照片,」#」表示陸地,」.」表示海洋。

照片保證第 1 行、第 1 列、第 N 行、第 N 列的像素都是海洋。

輸出格式

一個整數表示答案。

數據範圍

1N1000

輸入樣例1:

7
.......
.##.... .##.... ....##. ..####. ...###. ....... 

輸出樣例1:

1

輸入樣例2:

9
.........
.##.##... .#####... .##.##... ......... .##.#.... .#.###... .#..#.... ......... 

輸出樣例2:

1
解題思路:每一層的個數都是=2n-1個,並且開頭的下標都是2的倍數
代碼:
#include<iostream>
using namespace std;
const int N=100010;
typedef long long ll;
ll a[N];
ll maxn,sum,ans;
int main()
{
    ll i,j,n,k;
    cin>>n;
    for(i=1;i<=n;i++)
        cin>>a[i];
    maxn=a[1];
    ans=1;
    k=1;
    for(i=2;i<=n;i=i*2)
    {
        sum=0;
        for(j=i;j<=i*2-1&&j<=n;j++)
        {
            sum+=a[j];
        }
        k++;
        if(sum>maxn)
        {
            maxn=sum;
            ans=k;
        }
    }
    cout<<ans;
    return 0;
}
相關文章
相關標籤/搜索