(二分)scau校赛题目+poj2456

Treasure

Description

Li likes playing games. One of games names Finding Treasure. In the game, you have given a map (N*M). The coordinate坐标 (1,1) is the start position and (N , M) is the Treasure. There are monsters, walls, and grasslands in the map. A player can walk on grasslands, but not walls. In a map, a player can move up, down, left or right one step one block. The monsters can’t move, but they can fight against the player if a player meet one of them. Then, one of two results will happen. If the level of the player is greater or equal than the level of the monster. The player lives. Otherwise, the player dies. Of cause, no player want die. So, a player can train himself before starting his adventure. The question is : Given all the information of a map, what’s the minimal level a player need to get the treasure ,and the minimal steps?

Input

The first line has two integers, means N(row, 0<N<=50) and M(column, 0<N<=50)Then, following N lines. Each line contains M integer numbers. -1 represents a wall, 0 represents a grassland, X(0<X<1e9) represents a monster(X is the level of the monster)TIPS: It is possible that there is a monster on (1, 1) or (N, M).

Output

Each of two lines has a integer, first is the minimal level, second is the minimal steps. If can’t get the treasure, output only 1 line -- “nothing”

Sample Input 1

3 4
 1 -1  1  2
0  2  0  6
0  9  8  1

Sample Output 1

6
5

Hint

TIPS: (1, 1)-(2, 1)-(2, 2)-(2, 3)-(2, 4)-(3, 4)

对于二分,真的要去加强理解,特别是最后求出的下标l,r的所有含义更应该去弄得清清楚楚才行,这道题目利用二分等级去做...用了优先队列wa成狗了,二分等级后+bfs比较轻易就可以求出来了

#include<cstdio>
#include<algorithm>
#include<queue>
#include<iostream>
#include<cstring>
#include<cstdlib>
using namespace std;
struct node
{
    int x;
    int y;
    int step;
};
long long map[1000][1000];
int vis[1000][1000];
int dx[4]={-1,1,0,0};
int dy[4]={0,0,-1,1};
int n,m,flag,S;
int bfs(long long mid)
{
    //printf("mid==%lld\n",mid);
    queue<node>q;
    int x,y,step,i,j,k;
    node temp;
    temp.x=0;
    temp.y=0;
    temp.step=0;
    if(map[0][0]>mid)return -1;
    if(map[0][0]==-1)return -1;
    vis[0][0]=1;
    q.push(temp);
    while(!q.empty())
    {
        temp=q.front();
        q.pop();
        x=temp.x;
        y=temp.y;
        step=temp.step;
        //printf("x==%d  y==%d  step==%d\n",x,y,step);
        if(x==n-1&&y==m-1)
        {
            flag=1;
            return step;
        }
        for(k=0;k<=3;k++)
        {
            i=x+dx[k];
            j=y+dy[k];
            if(i<0||j<0||i>=n||j>=m||vis[i][j]||map[i][j]>mid||map[i][j]==-1) continue;
            vis[i][j]=1;
            temp.x=i;
            temp.y=j;
            temp.step=step+1;
            q.push(temp);
        }
    }
    return -1;
}
int main()
{
    long long i,j,k;
    long long L=0,R=0,mid,LEVEL;
    scanf("%d%d",&n,&m);
    for(i=0;i<=n-1;i++)
    {
        for(j=0;j<=m-1;j++)
        {
            scanf("%lld",&map[i][j]);
            R=max(R,map[i][j]);
        }
    }
    flag=0;
    while(L<=R)
    {
        memset(vis,0,sizeof(vis));
        mid=(L+R)/2;
        k=bfs(mid);
        if(k==-1)
        {
            L=mid+1;
        }
        else
        {
            LEVEL=mid;
            S=k;
            R=mid-1;
        }
    }
    if(flag) printf("%lld\n%d",LEVEL,S);
    else printf("nothing\n");
}
Time Limit: 1000MS Memory Limit: 65536K
Total Submissions: 18468 Accepted: 8792

Description

Farmer John has built a new long barn, with N (2 <= N <= 100,000) stalls. The stalls are located along a straight line at positions x1,...,xN (0 <= xi <= 1,000,000,000).

His C (2 <= C <= N) cows don't like this barn layout and become aggressive towards each other once put into a stall. To prevent the cows from hurting each other, FJ want to assign the cows to the stalls, such that the minimum distance between any two of them is as large as possible. What is the largest minimum distance?

Input

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

* Lines 2..N+1: Line i+1 contains an integer stall location, xi

Output

* Line 1: One integer: the largest minimum distance

Sample Input

5 3
1
2
8
4
9

Sample Output

3

Hint

OUTPUT DETAILS:

FJ can put his 3 cows in the stalls at positions 1, 4 and 8, resulting in a minimum distance of 3.

Huge input data,scanf is recommended.

Source

其实二分真的能运用的很广泛,如果能够看出是二分的话,做题真的不是一般的轻松,只要对于有序的数组去求解,一般利用二分是非常迅速的。

在这道题中,我们是要求出牛之间的最小距离中的最大值(就是如果牛之间的最小距离,然后在每一个最小距离的情况中取最大值)。先把牛栏从小到大排个序,然后二分距离,然后把这个距离去进行Judge比较,judge函数中,我们一定是先把第一头牛放入第一个牛栏中的,这是最优的放法,然后对于后面的牛,如果a[i]-cur>=mid的话,那么证明这头牛放入第i个牛栏中这个距离是可以的,然后继续进行下去,直到所有牛都放完。

最最重要的一点,就是二分最终的下标,如果mid这个距离是可以放的,那么我们就把整个距离扩大,因此l=mid+1,如果不能放,证明距离应该小一些,r=mid-1,那么我们最终得到的l值,一定是比我们要求的最大距离大1的,这个我们可以去自行模拟,这也是我觉得二分的最重要的思想。

#include <iostream>
#include <algorithm>
#include <cstdio>
using namespace std;
int n,m;
long long a[100009];
int cmp(int a,int b)
{
    return a<b;
}
int judge(long long mid)
{
    long long cur=a[0],k=1,i;//先把第一头牛放入0号槽
    for(i=1;i<=n-1;i++)
    {
        if(a[i]-cur>=mid)//找到一个比这个距离要大的位置可以放下一头牛
        {
            cur=a[i];
            k++;//放入牛
        }
        if(k==m) return 1;
    }
    return 0;
}
long long  BS()
{
    long long l=0,r=1000000009;
    int k;
    while(l<=r)
    {
        long long mid=(l+r)/2;
        k=judge(mid);
        if(k) l=mid+1;
        else r=mid-1;
    }
    return l-1;
}
int main()
{
    scanf("%d%d",&n,&m);
    int i;
    for(i=0;i<=n-1;i++)
    {
        scanf("%d",&a[i]);
    }
    sort(a,a+n,cmp);
   printf("%lld\n",BS());
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值