20200509栈队列总结

Fence Repair
补充优先队列知识

///普通优先队列  由大到小输出
priority_queue<int> q;
///由小到大输出
 priority_queue<int, vector<int>, greater<int> >q;
 /// 第二个参数为容器类型,第三个参数为比较函数

题目
Farmer John wants to repair a small length of the fence around the pasture. He measures the fence and finds that he needs N (1 ≤ N ≤ 20,000) planks of wood, each having some integer length Li (1 ≤ Li ≤ 50,000) units. He then purchases a single long board just long enough to saw into the N planks (i.e., whose length is the sum of the lengths Li). FJ is ignoring the “kerf”, the extra length lost to sawdust when a sawcut is made; you should ignore it, too.

FJ sadly realizes that he doesn’t own a saw with which to cut the wood, so he mosies over to Farmer Don’s Farm with this long board and politely asks if he may borrow a saw.

Farmer Don, a closet capitalist, doesn’t lend FJ a saw but instead offers to charge Farmer John for each of the N-1 cuts in the plank. The charge to cut a piece of wood is exactly equal to its length. Cutting a plank of length 21 costs 21 cents.

Farmer Don then lets Farmer John decide the order and locations to cut the plank. Help Farmer John determine the minimum amount of money he can spend to create the N planks. FJ knows that he can cut the board in various different orders which will result in different charges since the resulting intermediate planks are of different lengths.

Input
Line 1: One integer N, the number of planks
Lines 2… N+1: Each line contains a single integer describing the length of a needed plank
Output
Line 1: One integer: the minimum amount of money he must spend to make N-1 cuts
Sample Input
3
8
5
8
Sample Output
34
Hint
He wants to cut a board of length 21 into pieces of lengths 8, 5, and 8.
The original board measures 8+5+8=21. The first cut will cost 21, and should be used to cut the board into pieces measuring 13 and 8. The second cut will cost 13, and should be used to cut the 13 into 8 and 5. This would cost 21+13=34. If the 21 was cut into 16 and 5 instead, the second cut would cost 16 for a total of 37 (which is more than 34).

#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<cmath>
#include<algorithm>
#include<stack>
#include<queue>
#include<vector>
using namespace std;
int main()
{
    priority_queue<int, vector<int>,greater<int> >q;
    int n,i,j,k,a,b;
    long long num,ans;
    while(cin>>n)
    {
        ans=0;
        for(i=0;i<n;i++)
        {
            cin>>num;
            q.push(num);
        }
        while(q.size()>1)
        {
            a=q.top();
            q.pop();
            b=q.top();
            q.pop();
            q.push(a+b);
            ans+=a+b;
        }
        cout<<ans<<endl;
        while(!q.empty())
        q.pop();
    }
    return 0;
}

Bad Hair Day
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

6
10
3
7
4
12
2
Sample Output

5
我觉得这个题很有意思,题目要求每头牛能看到的牛的数目之和,我刚开始直接暴力数组解决,结果超时,但其实这个题可以反过来想,题目可以理解为求每头牛可以被其他牛看到的数目之和。
声明一个栈,每加入一个牛时,就把栈中的比该元素小的牛删除,这样栈中的牛就都能看到这头牛,栈中元素的个数即为能看到这头牛的个数。每次都把这头牛加入栈中,维护单调栈,可以得知栈中元素总是单调递减的。这样可以大大减小时间复杂度,即时间复杂度降为O(n)。
AC代码

#include<iostream>
#include<stack>
#include<cstdio>
#include<queue>
#include<algorithm>
using namespace std;
long long a[100005],i,j,k,ans,n,t;
stack<int>S;
int main()
{
    while(~scanf("%d",&n))
    {
        ans=0;
        scanf("%d",&t);
        S.push(t);
        for(i=1;i<n;i++)
        {
            scanf("%d",&t);
            while(!S.empty()&&t>=S.top())
                S.pop();
            ans+=S.size();
            S.push(t);
        }
        printf("%lld\n",ans);
    }
    return 0;
}

Stay Real
In computer science, a heap is a specialized tree-based data structure which is essentially an almost complete tree that satisfies the heap property: in a min heap, for any given node C, if P is a parent node of C, then the key(the value) of P is less than or equal to the key of C. The node at the ``top’’ of the heap(with no parents) is called the root node.

Usually, we may store a heap of size n in an array h1,h2,…,hn, where hi denotes the key of the i-th node. The root node is the 1-th node, and the parent of the i(2≤i≤n)-th node is the ⌊i2⌋-th node.

Sunset and Elephant is playing a game on a min heap. The two players move in turns, and Sunset moves first. In each move, the current player selects a node which has no children, adds its key to this player’s score and removes the node from the heap.

The game ends when the heap is empty. Both players want to maximize their scores and will play optimally. Please write a program to figure out the final result of the game.
Input
The first line of the input contains an integer T(1≤T≤10000), denoting the number of test cases.

In each test case, there is one integer n(1≤n≤100000) in the first line, denoting the number of nodes.

In the second line, there are n integers h1,h2,…,hn(1≤hi≤109,h⌊i2⌋≤hi), denoting the key of each node.

It is guaranteed that ∑n≤106.
Output
For each test case, print a single line containing two integers S and E, denoting the final score of Sunset and Elephant.
Sample Input
1
3
1 2 3
Sample Output
4 2

#include <iostream>
#include <cstdio>
#include <algorithm>
using namespace std;
typedef long long ll;
ll n,t,a[100005],i,j,k,sum1,sum2;
bool flag;
int main() {
    scanf("%lld", &t);
    while(t--){
        sum1=0;
        sum2=0;
        scanf("%lld",&n);
        for(i=0;i<n;i++) scanf("%lld",&a[i]);
        sort(a,a+n);
        for(i=n-1;i>=0;i--){
            if(!flag) sum1+=a[i];
            else sum2+=a[i];
        flag=!flag;
        }
        printf("%lld %lld\n",sum1,sum2);
    }
    return 0;
}
原创文章 25 获赞 38 访问量 835

猜你喜欢

转载自blog.csdn.net/weixin_46434074/article/details/105960914