dfs_bfs与二分

dfs与bfs

通俗的讲 (其实是我没文化 ,深搜便是在一个方向不断进行探索直到遇到瓶颈或达成目标再返回,然后再尝试另外一个方向,而广搜则是先对所有方向进行判断再进一步探索。由于深搜是依赖递归进行的(利用了递归进行回溯),所以说在什么时候进行回溯,回溯之后状态的清除等尤为重要。广搜依赖队列进行,需要熟悉队列的操作。此外bfs和dfs都是最暴力的遍历方式,有时需要恰当的剪枝。最经典的搜索题目应该是走迷宫了。


虽说都是暴搜,但有时在某些求最值的问题上bfs会比dfs快,因为bfs可以提前结束,而dfs则需要搜索到底才能结束。

A - Lake Counting

Due to recent rains, water has pooled in various places in Farmer John’s field, which is represented by a rectangle of N x M (1 <= N <= 100; 1 <= M <= 100) squares. Each square contains either water (‘W’) or dry land (’.’). Farmer John would like to figure out how many ponds have formed in his field. A pond is a connected set of squares with water in them, where a square is considered adjacent to all eight of its neighbors.

Given a diagram of Farmer John’s field, determine how many ponds he has.

input

* Line 1: Two space-separated integers: N and M

* Lines 2…N+1: M characters per line representing one row of Farmer John’s field. Each character is either ‘W’ or ‘.’. The characters do not have spaces between them.

Sample Input
10 12
W........WW.
.WWW.....WWW
....WW...WW.
.........WW.
.........W..
..W......W..
.W.W.....WW.
W.W.W.....W.
.W.W......W.
..W.......W.
Sample Output

3

大意就是求有多少“团”w,如果一个w的八个方向中有另一个w,那么他们就是同一团的,~(真滴词穷~,遍历数组,找到没有标记w,然后打上标记,ans+1,以这个w为基点,如果寻找到它周围的w,八个方向找完后就以新的w为基点,如此往复的去找,代码献上。

#include <iostream>
using namespace std;
#include <cstdio>
int ans=0;
char field[105][105];
bool vis[105][105];
int pos[9][2]={{0,0},{-1,1},{0,1},{1,1},{-1,0},{1,0},{-1,-1},{0,-1},{1,-1}};
void flat (int x,int y){
    vis[x][y]=true;
    for(int i=1;i<=8;i++)
        if(field[pos[i][0]+x][pos[i][1]+y]=='W')
            if(vis[pos[i][0]+x][pos[i][1]+y]==false){
                flat(pos[i][0]+x,pos[i][1]+y);
            }
}
void solve(int x,int y){
    if(vis[x][y]==false){
        ans++;
        flat(x,y);
    }
}
int main(){
    int n,m;
    cin>>n>>m;
    for(int i=1;i<=n;i++){
        for(int j=1;j<=m;j++)
            scanf(" %c",&field[i][j]);
    }
    for(int i=0;i<=n+1;i++)
        field[i][0]=field[i][m+1]='.';
    for(int j=0;j<=m+1;j++)
        field[0][j]=field[n+1][j]='.';
    for(int i=1;i<=n;i++)
        for(int j=1;j<=m;j++)
            if(field[i][j]=='W')
                solve(i,j);
    cout<<ans;
}

二分

二分查找就是再一个有序数组里寻找某个值,通过不断判断中间值与目标的大小关系来缩小范围,可达到log(n)的速度。二分答案与二分查找颇有类似,不同之处在于二分答案并非简单的比较数值大小,而是通过某种方式去进行比较,最常见的题型是求最大的最小值 (或最小的最大值)。二分的细节之处有许多,mid的取法、区间的开闭、边界的处理等。对应不同的情况二分有相对应的模板。

G - MaratonIME gets candies

Obs: this is an interactive problem. More information is under the “Interaction” section.

MaratonIME is gathering to start another group practice. This time, Renzo decided to reward the students with candies as they solve problems. Curious as they are, the members of MaratonIME started to guess how many candies did Renzo bring. For each question, Renzo answered if the amount of candies was higher, lower or equal to the number asked.

Breno, noticing that the amount of candies could be very high, decided to limit the number of queries to 50. This way, the practice would start as soon as possible.

Renzo bought at least 1 and no more than 109 candies. Find how many candies were bought by Renzo with no more than 50 questions.

input

For every question asked, read a character. It will be " > " if the amount of Renzo’s candies is higher than your guess, " < " if the amount of Renzo’s candies is lower than your guess or " = " if your guess is equal to the amount of Renzo’s candies.

output

You must print every query in the format “Q y”, where y is the number guessed, and 1 ≤ y ≤ 10^9. After printing a question, you need to flush the output. Check the “Interaction” section for examples of how to flush the output.

Interaction

To ask Renzo a question, print the query in the format above. After printing a question, you need to flush the output. See examples below for each language:

C: fflush(stdout)

C++: cout.flush()

Java: System.out.flush()

Python: sys.stdout.flush()

Pascal: flush(output)

After each query, read a character as described above.

As soon as Renzo answers your question with “=” the program has to terminate. Your answer will be considered correct if you asked no more than 50 questions.

二分交互题,在1-- 1e9的范围内求一个数,你可以询问一个数,系统会回答大于小于或等于。二分模板题。

#include <iostream>
using namespace std;
int main(){
    int  num,temp = 5e8;
    char ch;
    int l = 1, r = 1e9;
    while(1){
        int mid = (l + r) >> 1;
        cout << "Q " << mid <<endl;
        cin >> ch;
        if(ch == '=')
            break;
        if(ch == '<'){
            r = mid - 1;
        }
        else if(ch == '>'){
            l = mid + 1;
        }
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值