poj-3250 Bad Hair Day

Bad Hair Day
Time Limit: 2000MS   Memory Limit: 65536K
Total Submissions: 25110   Accepted: 8546

Description

Some of Farmer John's N cows (1 ≤ N ≤ 80,000) are having a bad hair day! Since each cow is self-conscious about her messy hairstyle, FJ wants to count the number of other cows that can see the top of other cows' heads.

Each cow i has a specified height hi (1 ≤ h≤ 1,000,000,000) and is standing in a line of cows all facing east (to the right in our diagrams). Therefore, cow i can see the tops of the heads of cows in front of her (namely cows i+1, i+2, and so on), for as long as these cows are strictly shorter than cow i.

Consider this example:

        =
=       =
=   -   =         Cows facing right -->
=   =   =
= - = = =
= = = = = =
1 2 3 4 5 6

Cow#1 can see the hairstyle of cows #2, 3, 4
Cow#2 can see no cow's hairstyle
Cow#3 can see the hairstyle of cow #4
Cow#4 can see no cow's hairstyle
Cow#5 can see the hairstyle of cow 6
Cow#6 can see no cows at all!

Let ci denote the number of cows whose hairstyle is visible from cow i; please compute the sum of c1 through cN.For this example, the desired is answer 3 + 0 + 1 + 0 + 1 + 0 = 5.

Input

Line 1: The number of cows, N
Lines 2..N+1: Line i+1 contains a single integer that is the height of cow i.

Output

Line 1: A single integer that is the sum of c1 through cN.

Sample Input

6
10
3
7
4
12
2

Sample Output

5

Source

 
先挂TLE代码,果然靠自己想就是不太行orz,必须要用单调队列/单调栈。。
#include <iostream>
#include <algorithm>
#include <cmath>
#include <stdio.h>
#include <cstring>
#include <string>
#include <cstdlib>
#include <queue>
#include <stack>
#include <set>
#include <vector>
#include <map>
#include <list>
#include <iomanip>
 #include <fstream>
using namespace std;
typedef long long ll;

int cow[80000+1];
int ans[80000+1];
int main()
{
    int n;
    memset(cow,0,sizeof(cow));//记住不要成为全局变量自己初始化的奴隶 
    memset(ans,0,sizeof(ans));//自己亲自手动初始化才靠谱
    scanf("%d",&n); 
    for(int i=n;i>=1;--i)
        scanf("%d",&cow[i]);//倒着读  
    
    int pre=1,super=0;
    for(int i=1;i<=n;++i)
    {
        int cnt=0;//计算当前奶牛可以看到的其他奶牛的发型数量。 
        //第一个它肯定是看不到东西的,不过用来记录它是从1~1的最大值 
        if(cow[i]>cow[pre]){
            cnt=i-pre+ans[pre];//下标相减是两个极大值之间的奶牛数+先出现的那只极大值奶牛,再加上它之前能看到的奶牛//printf("因为%d大于%d了,所以cnt=%d\n",i,pre,cnt); 
         }//必须是严格大于才看得到发型 
        else if(cow[i]<=cow[pre]){
            for(int j=i-1;j>pre;j--)
            {
                if(cow[i]<=cow[j])
                    break;
                else
                    cnt++;
            }//printf("因为%d小于%d了,所以cnt=%d\n",i,pre,cnt); 
        }     
        if(super<=cow[i]){//用等号是因为 假如时隔很久才出现一个与原来最大值一样大的数,但是它的坐标需要更新一波 
            super=cow[i];//那么下一个数最邻近右边的最大值是这次遍历到的数 
            pre=i;//记录一下这个数的下标 
        }
        ans[i]=cnt;
    }
    ll final=0;
    for(int i=1;i<=n;++i)
    {
        final+=ans[i];
    }
    
    printf("%I64d\n",final);
    return 0;
}
TLE

单调栈。

#include <iostream>
#include <algorithm>
#include <cmath>
#include <stdio.h>
#include <cstring>
#include <string>
#include <cstdlib>
#include <queue>
#include <stack>
#include <set>
#include <vector>
#include <map>
#include <list>
#include <iomanip>
 #include <fstream>
using namespace std;
typedef long long ll;

int cow[80000+1];
int main()
{
    int n=0;
    memset(cow,0,sizeof(cow));
    scanf("%d",&n); 
    int h=0,t=0,final=0;
    for(int i=1;i<=n;++i)
    {
        scanf("%d",&h);
        while(t>0&&cow[t-1]<=h)
            t--;
        final+=t;
        cow[t]=h;
        t++;
    }
    printf("%I64d\n",final);
    return 0;
}
AC

 

 
posted @ 2019-07-20 15:38  鹤花之歌  阅读(135)  评论(0编辑  收藏  举报