1. 程式人生 > >UVA 11882 Biggest Number (搜尋+剪枝(dfs+bfs))

UVA 11882 Biggest Number (搜尋+剪枝(dfs+bfs))

題意:在一個R行C列(2R,C15,RC30)的矩陣裡有障礙物和數字格(包含1~9的數字)。你可以從任意一個數字格出發,每次沿著上下左右之一的方向走一格,但不能走到障礙格中,也不能重複經過一個數字格,然後把沿途經過的所有數字連起來,如圖所示。如圖可以得到9784,4832145等整數。問:能得到的最大整數是多少?(本段摘自《演算法競賽入門經典(第2版)》)

最大的數示意圖

分析:
列舉起點進行DFS即可。有一個最優性剪枝,即噹噹前位置的時候,剩下可以走的最大長度加上已走長度如果仍然小於當前最優的答案時,直接return,如果相等但是字典序比當前最優答案小的話也直接return。

#include<bits/stdc++.h>
using namespace std;
char s[22][22];
int vis[22][22],vis1[22][22],a[33];
int dx[]={-1,0,1,0};
int dy[]={0,1,0,-1};
int n,m;
struct P
{
    int x,y;
    P(int x,int y):x(x),y(y){}
    P(){}
};
string ans;
int bfs(int x,int y)
{
    int i,j,tx,ty,len=0;
    queue<P>que;
    que.push(P(x,y));
    vis1[x][y]=1;
    while(!que.empty()) {
        P p = que.front();
        que.pop();
        for(i=0;i<4;i++) {
            tx=p.x+dx[i];
            ty=p.y+dy[i];
            if(tx<0||tx>=n||ty<0||ty>=m||vis[tx][ty]||vis1[tx][ty]||s[tx][ty]=='#') continue;
            vis1[tx][ty]=1;
            a[len++]=s[tx][ty]-'0';
            que.push(P(tx,ty));
        }
    }
    return len;
}
void dfs(int x,int y,string tmp)
{
    int i,j,tx,ty;
   // cout<<tmp<<endl;
   ///////////////////////////////////// 剪枝
    if(tmp.length()>ans.length()||(tmp.length()==ans.length() && tmp>ans)) ans=tmp;
    else {
        memset(vis1,0,sizeof(vis1));
        int len = bfs(x,y);
        if(ans.length()>tmp.length()+len) return;
        sort(a,a+len,greater<int>());
        string t = tmp;
        for(i=0;i<len;i++) {
            t+=char(a[i]+'0');
        }
        if(ans.length()==t.length() && ans>t) return ;
    }
    
    //////////////////////////////////// 剪枝
    
    for(i=0;i<4;i++) {
        tx=x+dx[i],ty=y+dy[i];
        if(tx<0||tx>=n||ty<0||ty>=m||vis[tx][ty]||s[tx][ty]=='#') continue;
        vis[tx][ty] = 1;
        dfs(tx,ty,tmp+s[tx][ty]);
        vis[tx][ty]=0;
    }
}
int main()
{
    int i,j;
    string tmp;
    ios::sync_with_stdio(false);
    while(cin>>n>>m) {
        if(n==0 && m==0) break;
        for(i=0;i<n;i++) cin>>s[i];
        ans="";
        for(i=0;i<n;i++) {
            for(j=0;j<m;j++) {
                tmp="";
                if(s[i][j]=='#') continue;
                vis[i][j]=1;
                dfs(i,j,tmp+s[i][j]);
                vis[i][j]=0;
            }
        }
        cout<<ans<<endl;
    }
    return 0;
}


相關推薦

UVA 11882 Biggest Number 搜尋+剪枝dfs+bfs

題意:在一個R行C列(2≤R,C≤15,R∗C≤30)的矩陣裡有障礙物和數字格(包含1~9的數字)。你可以從任意一個數字格出發,每次沿著上下左右之一的方向走一格,但不能走到障礙格中,也不能重複經過一個數字格,然後把沿途經過的所有數字連起來,如圖所示。如圖可以得到978

UVa 11882 Biggest Number 題解

代碼 原則 log 字符串 題目 stl 分分鐘 建議 函數 難度:β- 建議用時:30 min 實際用時:3 h 題目:?? 代碼:?? 這題的算法真的不難,剪枝也很容易想到。 主要問題在卡時間。 這題如果不用一些節省時間的辦法,分分鐘 TLE。 要節省時間有

UVaBiggest Numberdfs+剪枝

scanf sin ret break puts 從大到小 如果 ssl ges 題目 題目 ? ? 分析 典型搜索,考慮剪枝。 統計一下聯通分量。 1、本位置能夠達到所有的點的數量加上本已有的點,還沒有之前的結果長,直接返回。 2、當本位置能夠達到所有的點的數量加上本

uva live 7638 Number of Connected Components 並查集

txt 通過 open main eps div cte efi ive 題目鏈接:https://icpcarchive.ecs.baylor.edu/index.php?option=com_onlinejudge&Itemid=8&page=show_

poj 1011 hdoj 1455 Sticks搜尋+剪枝

題目連結 大致題意: 有n跟棍, 求它們能組成最短且長度相同的棍的長度 解題思路: DFS+剪枝 POJ2362的強化版,重點在於剪枝   建議你先看看這道題  here 令initlen為所求的最短原始棒長,maxlen為給定的棒子堆中最長的棒子,su

HDU 1045 Fire Net搜尋剪枝

http://acm.split.hdu.edu.cn/showproblem.php?pid=1045 題目連結(總有一個可以點開)…… 題意:給出一張地圖,上面只有兩種字元(.和X),X相當於無法穿透的牆。問這張地圖上最多可以放置多少個互不攻擊的子彈…… 第一反應是

改變android手機搜尋鍵行為搜尋鍵替換為電源鍵

LZ苦逼程式設計師一枚 用了個破G14阿  這幾天讓我很惱火的就是電源鍵阿 按多了 都不怎麼靈  google一頓 找到了解決方案。特與大家分享。 手機必須有root許可權。 更改搜尋鍵為:按一下鎖屏,長按出現電源選單!!!!!(2.3.5的rom)1、開啟RE管理器並找

leetcode 35 Search Insert Position.搜尋元素插入陣列的位置

題目要求: 給定一個排好順序陣列和一個目標值,搜尋陣列,如果找到目標,那麼返回索引。如果沒有,那麼返回該目標值應該插入陣列的位置索引。 假設陣列中沒有重複項。 Example: 例1 輸入: [1,3,5,6], 5 輸出:2 例2 輸入: [1,3,5,6], 2 輸

2017愛奇藝實習面試總結搜尋開發,拿到offer

一面-大概下午兩點多 1、  實習做得伺服器架構 2、  實習主要做了哪些事情 3、  實習開發的伺服器併發量多大?中有碰到過因為大量併發連線而造成的宕機嗎? 4、  TCP/IP 的瞭解,連線 3 次握手和關閉 4 次揮手, time_wait 的作用 5、  One loop per thr

240. Search a 2D Matrix II搜尋二維矩陣之二

這道題沒什麼好說的,沒有太大的難度,很快就AC了。簡單說一下思路:觀察可知越往右下數越大,加上每一行最後一個數是該行最大值,因此可以根據列值減少搜尋的列數。定義 i 為矩陣的行,j 為矩陣的列,初始化 i 為0,j 為最後一列。若目標值大於當前matrix [ i ][ j

HDU 2289搜尋題,二分、幾何

Cup Time Limit: 3000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 486    Accepted Submission(s):

12.6日總結 最小度限制生成樹 POJ 1639含聯通塊dfs劃分模板

     今天看了 一道 有度數限制的最小生成樹題目,按照書上給出的思路寫的程式碼,思路的最後一步沒有實現,可能沒弄懂書上的意思。 http://poj.org/problem?id=1639。 題意:     大概是說在一張無向圖中

Frame Stacking拓撲排序+dfs+建圖

K - Frame Stacking Consider the following 5 picture frames placed on an 9 x 8 array.  ........ ........ ........ ........ .CCC....

訪問最短路+搜尋剪枝

2247: 訪問(deliver) 題目描述 給你一個n個頂點的鄰接矩陣(圖),以及每個頂點的訪問時限,要求從頂點1開始,尋找一個訪問序列,要求在每個頂點的訪問時限之前訪問,且每個頂點的訪問時間之和最小 輸入 第一行一個數n,2&l

Uva - 10047 】The Monocycle搜尋bfs記錄狀態

題幹: Uva的題目就不貼上題幹了,,直接上題意吧。 有你一個獨輪車,車輪有5種顏色,為了5中顏色的相對位置是確定的。有兩種操作:1.滾動:輪子必須沿著順時針方向滾動,每滾動一次會到達另一個格子,著地的顏色會改變(順時針轉)。例如當前是綠色著地下一次就是黑色,依次是紅藍白。2.轉動:就是

LeetCode 39組合總和 [DFS: 暴力搜尋 + 剪枝 + 去重]

39. 組合總和 給定一個無重複元素的陣列 candidates 和一個目標數 target ,找出 candidates 中所有可以使數字和為 target 的組合。 candidates 中的數字可

LeetCode 39組合總和 [DFS: 暴力搜尋 + 剪枝 + 去重]

39. 組合總和 給定一個無重複元素的陣列 candidates 和一個目標數 target ,找出 candidates 中所有可以使數字和為 target 的組合。 candidates 中的數字可以無限制重複被選取。 說明: 所有數字(包括 target)都是正整數。

搜尋3:重複性剪枝 poj1011

POJ 1011 在民國某年,少林寺被軍閥炮轟,這些棍子被炸成 N 節長度各異的小木棒 戰火過後,少林方丈想要用這些木棒拼回原來的棍子 可他記不得原來到底有幾根棍子了,只知道古人比較矮,且為了攜帶方便,棍子一定比較短 他想知道這些棍子最短可能有多短

191. Number of 1 BitsLeetCode

fun 其他 represent num span take style bin eight Write a function that takes an unsigned integer and returns the number of ’1‘ bits it has

UVa 11419 我是SAM最小點覆蓋+路徑輸出

二分圖 現在 over div space void net https 最小點覆蓋 https://vjudge.net/problem/UVA-11419 題意:一個網格裏面有一些目標,可以從某一行,某一列發射一發子彈,可以打掉它;求最少的子彈,和在哪裏打?