码迷,mamicode.com
首页 > 其他好文 > 详细

扔盘子(思维)

时间:2017-10-01 13:13:04      阅读:209      评论:0      收藏:0      [点我收藏+]

标签:==   开始   www.   一个   ios   put   bsp   个数   也有   

有一口井,井的高度为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<iostream>  
#include<cstring>  
#include<math.h>  
#include<stdlib.h>  
#include<cstring>  
#include<cstdio>  
#include<utility>  
#include<algorithm>  
#include<map>  
#include<stack>  
using namespace std;  
typedef long long ll;  
const int Max = 1e5+5;  
const int mod = 1e9+7;  
const int Hash = 10000;  
const int INF = 1<<30;  
const ll llINF = 1e18;  
  
int n, m;  
int well[Max], plate[Max];  
int main( )  
{  
    //freopen("input.txt", "r", stdin);  
    while(cin>>n>>m)  
    {  
        int ans = 0, Min = INF;  
        for(int i=0; i<n; i++)  
            scanf("%d", well+i);  
        for(int i=0; i<m; i++)  
            scanf("%d", plate+i);  
        //预处理,用单调栈来处理数据  
        stack<int> st;  
        for(int i=0; i<n; i++)  
        {  
            if(well[i]<Min)  
                Min = well[i];  
            st.push(Min);  
        }  
        int k = 0;  
        while(!st.empty() && k<m)//井满或者盘子用尽都结束  
        {  
            if(st.top()<plate[k])//盘子大继续出栈  
            {  
                st.pop( );  
                continue;  
            }  
            ans++;//在这个位置卡住一个盘子  
            st.pop( );  
            k++;  
        }  
        cout<<ans<<endl;  
    }  
    return 0;  
}

  

 

扔盘子(思维)

标签:==   开始   www.   一个   ios   put   bsp   个数   也有   

原文地址:http://www.cnblogs.com/ruruozhenhao/p/7617015.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!