题目链接:https://www.51nod.com/question/index.html#!questionId=1132
这道题真是一波三折啊,最开始没有思路,看了看大神的blog,看到写的是先预处理,把井的宽度从大到小排序,自己以为是改变这些宽度的顺序,我一直理解不了为什么。。。。后来还是自己想明白了,原来是理解的有问题,应该是不改变顺序,而是遍历一遍,如果不是上面一个比下面的大,就将下面那个改成与上面同样大小,而达到宽度形成倒梯形的目的,至于为什么要这样做,我在这里大体说一下,你想想 如果上面的比下面的小,那其实是没有意义的,既然上面小的那个都过不去,下面再宽也没有用
这里我自己还犯了一个错误就是我习惯性的把inf设成0xfffffff,没有注意到这个题最大是1e9,唉,在这wa了好几次,
最后看大神代码还学习到了一个C++的二分用到的函数lower_bound,返回第一个大于n的地址,点这里看具体的使用方法
AC代码:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#define MAX 50010
#define inf 1e9+110
long long int w[MAX],d[MAX];
using namespace std;
int main()
{
int n,m,i,j;
while(scanf("%d%d",&n,&m)!=EOF)
{
for(i=n;i>=1;i--)
scanf("%lld",&w[i]);
w[n+1]=w[0]=inf;
for(i=1;i<=n;i++)
{
w[n-i+1]=min(w[n-i+1],w[n-i+2]);
}
int tp=1;
int sum=0;
for(j=1;j<=m;j++)
{
scanf("%lld",&d[j]);
}
for(j=1;j<=m;j++)
{
int tmp=lower_bound(w+tp,w+n+1,d[j])-w;
// printf("%d\n",tmp);
if(tmp==n+1) break;
tp=tmp+1;
sum++;
}
cout<<sum<<endl;
}
return 0;
}