扔盘子(思维)

有一口井,井的高度为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;
}

  

用栈的方法来解

#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

 

温故而知新

  

 

posted @ 2017-10-01 12:39  Veritas_des_Liberty  阅读(888)  评论(0编辑  收藏  举报