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
Lines 2..N+1: Line i+1 contains a single integer that is the height of cow i.
Output
Sample Input
6 10 3 7 4 12 2
Sample Output
5题目大意:题目挺好懂的,就是数出右边比左边矮的牛的个数
最开始写了个双重循环,超时了
#include <iostream>
#define MAXN 80000
int 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 80000
long 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 80000
long 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 |
#include <iostream>
//#include <stack>
#include <cstring>
#define MAXN 80000
long long N,height[MAXN+2];
#define MAXSIZE 90000
template<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 80000
int N,height[MAXN+2];
#define MAXSIZE 90000
template<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;
}