Bad Hair Day
| Time Limit: 2000MS |
|
Memory Limit: 65536K |
| Total Submissions: 10988 |
|
Accepted: 3705 |
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 ≤ hi ≤ 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
610374122
Sample Output
5
題目大意:題目挺好懂的,就是數出右邊比左邊矮的牛的個數
最開始寫了個雙重迴圈,逾時了
#include <iostream>#define MAXN 80000int N,height[MAXN+2];int main(){using namespace std;while(cin>>N){for(int i=1;i<=N;++i)cin>>height[i];int ans=0;for(int i=1;i<=N;++i)for(int j=i+1;j<=N;++j)if(height[j]<height[i])++ans;else break;cout<<ans<<endl;}return 0;}
然後本來就是查閱棧資料才找到這道題的,所以自然用棧來寫了。仔細想了一下,自己想出了一個棧類比,思路是這樣的:
從後向前遍曆高度數組,指標為i,將高度入棧,如果棧頂的高度小於現在i的高度,那麼就一直出棧,直到棧空或者棧頂的高度比較小,此時出棧的個數就是此時的牛i所能看到的牛的數目,同時用vist將這個數字儲存下來。下次如果牛i被出棧,那麼那頭牛看到的個數還得加上牛i看到的牛的個數。代碼如下
#include <iostream>#include <stack>#include <cstring>#define MAXN 80000long long N,height[MAXN+2];long long vist[MAXN+2];int main(){using namespace std;cin>>N;for(long long i=1;i<=N;++i)cin>>height[i];long long ans=0; memset(vist,0,sizeof(vist));stack<long long>s;s.push(height[N]);for(int i=N-1;i>=1;--i){if(!s.empty() && s.top()>=height[i])s.push(height[i]);else{long long temp=0;while (!s.empty() && s.top()<height[i]){if(vist[s.top()])temp+=vist[s.top()];++temp;s.pop();}ans+=temp;vist[height[i]]=temp;s.push(height[i]);}}cout<<ans<<endl;return 0;}
測試資料都過了,自己也測試了下是對的,結果一直RE,仔細一想,原來是那個牛怎麼那麼高啊,難怪RE,我得vist數組最大才80000,結果那些牛巨高,遠遠超過了我數組的大小,這樣的話看來得換個方法。
然後自然而然的去看了一下別人的代碼,原來別人是順序遍曆的,(我之前的思路是逆序)。當然這不是關鍵,關鍵是用棧的裡儲存的數目來替代那個vist,所以才需要順序遍曆,因此代碼修改如下
| 11360988 |
TSERROF |
3250 |
Accepted |
2648K |
1204MS |
C++ |
529B |
2013-03-17 18:56:51 |
#include <iostream>#include <stack>#include <cstring>#define MAXN 80000long long N,height[MAXN+2];int main(){using namespace std;while(cin>>N){for(long long i=1;i<=N;++i)cin>>height[i];long long ans=0; stack<long long>s;s.push(height[1]);for(int i=2;i<=N;++i){while(!s.empty() && s.top()<=height[i])s.pop();if((!s.empty() && s.top()>height[i]) || s.empty()){ans+=s.size();s.push(height[i]);}}cout<<ans<<endl;}return 0;}
如果用自己的棧的話
| 11361036 |
TSERROF |
3250 |
Accepted |
1488K |
688MS |
C++ |
1578B |
2013-03-17 19:03:22 |
不過貢獻了兩次WA,首先我原來沒寫size函數,齊次我空間開小了,我把MAXSIZE改成了9w
#include <iostream>//#include <stack>#include <cstring>#define MAXN 80000long long N,height[MAXN+2];#define MAXSIZE 90000template<typename T>class stack{private:T *STACK;long long TOP;public:stack();~stack();bool pop();bool push(T);T top();bool empty();void show(bool);long long size();};template<typename T> stack<T>::stack(){STACK=new T[MAXSIZE];TOP=-1;}template<typename T> stack<T>::~stack(){delete STACK;}template<typename T> bool stack<T>::pop( ){if(TOP==-1)return false;--TOP;return true;}template<typename T> bool stack<T>::push(T d){if(TOP==MAXSIZE-1)return false;STACK[++TOP]=d;return true;}template<typename T>T stack<T>::top(){return STACK[TOP];}template<typename T> bool stack<T>::empty(){if(TOP==-1)return true;return false;}template<typename T> void stack<T>::show(bool reverse){if(reverse){for(int i=TOP;i>=0;--i)std::cout<<STACK[i]<<" ";}else{for(int i=0;i<=TOP;++i)std::cout<<STACK[i]<<" ";}}template<typename T>long long stack<T>::size(){return TOP+1;}int main(){using namespace std;while(cin>>N){for(long long i=1;i<=N;++i)cin>>height[i];long long ans=0; stack<long long>s;s.push(height[1]);for(int i=2;i<=N;++i){while(!s.empty() && s.top()<=height[i])s.pop();if((!s.empty() && s.top()>height[i]) || s.empty()){ans+=s.size();s.push(height[i]);}}cout<<ans<<endl;}return 0;}
其實也完全沒必要用long long,改成int後空間減小了不少
| 11361054 |
TSERROF |
3250 |
Accepted |
904K |
688MS |
C++ |
1542B |
2013-03-17 19:05:52 |
#include <iostream>//#include <stack>#include <cstring>#define MAXN 80000int N,height[MAXN+2];#define MAXSIZE 90000template<typename T>class stack{private:T *STACK;int TOP;public:stack();~stack();bool pop();bool push(T);T top();bool empty();void show(bool);int size();};template<typename T> stack<T>::stack(){STACK=new T[MAXSIZE];TOP=-1;}template<typename T> stack<T>::~stack(){delete STACK;}template<typename T> bool stack<T>::pop( ){if(TOP==-1)return false;--TOP;return true;}template<typename T> bool stack<T>::push(T d){if(TOP==MAXSIZE-1)return false;STACK[++TOP]=d;return true;}template<typename T>T stack<T>::top(){return STACK[TOP];}template<typename T> bool stack<T>::empty(){if(TOP==-1)return true;return false;}template<typename T> void stack<T>::show(bool reverse){if(reverse){for(int i=TOP;i>=0;--i)std::cout<<STACK[i]<<" ";}else{for(int i=0;i<=TOP;++i)std::cout<<STACK[i]<<" ";}}template<typename T>int stack<T>::size(){return TOP+1;}int main(){using namespace std;while(cin>>N){for(int i=1;i<=N;++i)cin>>height[i];long long ans=0; stack<int>s;s.push(height[1]);for(int i=2;i<=N;++i){while(!s.empty() && s.top()<=height[i])s.pop();if((!s.empty() && s.top()>height[i]) || s.empty()){ans+=s.size();s.push(height[i]);}}cout<<ans<<endl;}return 0;}