有一口井,井的高度为N,每隔1个单位它的宽度有变化。现在从井口往下面扔圆盘,如果圆盘的宽度大于井在某个高度的宽度,则圆盘被卡住(恰好等于的话会下去)。


盘子有几种命运:1、掉到井底。2、被卡住。3、落到别的盘子上方。


盘子的高度也是单位高度。给定井的宽度和每个盘子的宽度,求最终落到井内的盘子数量。


 




 



如图井和盘子信息如下:


井:5 6 4 3 6 2 3


盘子:2 3 5 2 4


 


最终有4个盘子落在井内。


本题由   ​​@javaman​​  翻译。


Input第1行:2个数N, M中间用空格分隔,N为井的深度,M为盘子的数量(1 <= N, M <= 50000)。 

第2 - N + 1行,每行1个数,对应井的宽度Wi(1 <= Wi <= 10^9)。 

第N + 2 - N + M + 1行,每行1个数,对应盘子的宽度Di(1 <= Di <= 10^9)Output输出最终落到井内的盘子数量。Sample Input

7 5
5
6
4
3
6
2
3
2
3
5
2
4


Sample Output

4


刚开始想的是用两个队列来维护,但是.......后来用两个数组来存放盘子和井的宽度由于用到了两重循环结果TLE了



#include<bits/stdc++.h>
#define maxn 50010
using namespace std;

int main()
{
int n,m;
int i,j;
int flag;
int logo;
int a[maxn],b[maxn];
scanf("%d%d",&n,&m);
a[0] = 0;
for(i=1; i<=n; i++)
{
scanf("%d",&a[i]);
}
for(i=0; i<m; i++)
{
scanf("%d",&b[i]);
}
flag = n;
for(j=0; j<m; j++)
{
logo = 1;
for(i=0; i<flag; i++)
{
if(b[j] > a[i])
{
flag = i;
logo = 0;
}
}
if(logo == 1)
flag--;
if(flag == 0)
{
printf("%d\n",j);
break;
}
}

return 0;
}


  

 

 

然后看了大神的博客发现时间复杂度可以简化到O(n),具体的方法就是让井的下层宽度小于或者等于上层宽度,然后从上往下以此比较

 



#include<bits/stdc++.h>
#include<string.h>
#define maxn 50010
using namespace std;

int main()
{
int n,m;
int i,j;
int flag;
int a[maxn],b[maxn];
scanf("%d%d",&n,&m);
for(i=1; i<=n; i++)
{
scanf("%d",&a[i]);
if(i >= 2)
a[i] = min(a[i],a[i-1]);
}
flag = 0;
for(j=0; j<m; j++)
{
scanf("%d",&b[j]);
while(a[n] < b[j])
n--;
if(n > 0)
{
flag++;
n--;
}
}
printf("%d\n",flag);
return 0;
}


  

用栈的方法来解


扔盘子(思维)_数组扔盘子(思维)_c++_02


#include<stdio.h>
#include<string.h>
#include<stack>
const int M = 50005;

using namespace std;

int main()
{
int n, m;
int i, j, k;
int well[M], plate[M], a[M];
int ans = 0;

stack<int> s;

scanf("%d %d", &n, &m);

for( i = 0; i < n; i++ )
{
scanf("%d", &well[i]);
}

for( i = 0; i < m; i++ )
{
scanf("%d", &plate[i]);
}

s.push(well[0]);

for( i = 1; i < n; i++ )
{
if(well[i] > well[i-1])
{
well[i] = well[i-1];
}

s.push(well[i]);
}

for( i = 0; i < m; i++ )
{
while(!s.empty())
{
if(s.top() >= plate[i])
{
ans++;
s.pop();
break;
}

else
s.pop();
}
}

printf("%d", ans);

return 0;

}

View Code

 

温故而知新

  

 


永远渴望,大智若愚(stay hungry, stay foolish)