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
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
* Lines 2..N+1: Line i+1 contains an integer stall location, xi
Output
Sample Input
5 3 1 2 8 4 9
Sample Output
3
Hint
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());
}