問題解決羅区P1823 [COI2007]パトリックのコンサートを待ち

P1823 [COI2007]パトリックコンサート待機

タイトル説明

Nの人々がコンサートを入力するまでキューイングされています。それは退屈だったというように、そう、彼らはランクの彼の知人を探して、電源を入れ始めました。それらはAまたはBよりも高くない、隣接する又はそれらの間にある場合、任意の2つの待ち行列A及びBは、それらはお互いに見えます。

多くの人々がお互いを見ることができるかを計算するプログラムを書きます。

入力形式

入力の最初の行は、整数N(500 000≤1≤N)が含まれ、Nは、個々のランクの合計を意味します。

ナノメートルの次のN行、各行が人物の高さを示す整数が含まれ、(電力計10の-9等しい)単位として、各スケジューリング未満2 ^ 31 nmです。これらのチームは、身長の高さを表しています。

出力フォーマット

S、Sの数を含む出力のみ1行が人の合計チームがお互いを見ることができ表します。

サンプル入力と出力

入力#1

7
2
4
1
2
2
5
1

出力#1

10

説明/ヒント

データ制作:@w

データ2018年6月29日の3組の追加

[思考]

単調なスタック
非常に興味深いトピック

[タイトル]効果

キュー
中間2つの1が彼らのそれぞれが見ることができるよりも高くない限り、
お互いが数で見ることができます

【合理的な分析]

お互いを見ることができない。この点は、両者の間に1ベーシスそれらのいずれかよりも高いに基づいて
、人の最も遠いの両側に彼より最初の高い人見ることができる
権利、それは明らかである。この?
彼は彼がブロックされたよりも高い最初の人だった後なので
(実際にフィット)
し、その後、この男は、彼の最初の側面よりも高ければ
、この人を見ることができない可能性のあるすべての人々の間で

:ので
1145141919
最も遠い位置8を参照するには、右側の9は1 1上の位置であることを
位置までが、1と8の間のすべての数字の位置
彼がお互いを見ることができなかった
、など1 5位置に
お互いを見ることができない
中間位置があるため、4 1 6よりも高い
ので、互いに参照
番号8を参照する権利上の9位見
541が
明らかにこれは大きいがインターバルの右に増加
しますが、最初の1の後に右側に見るように
、右側の最初のものよりも低くすることができない第二の右に見える
か、見られることではありません

【対照的に】

それが明確であることではないですか?
その単調なスタックではありません!

[思考]ファイナル

上記のプロセスは完全に単調なスタックは右のプロセスであるである
最上位の要素内のスタックは要素の手よりも小さい場合には
先頭の要素の最後の要素はの手を参照することができます左の
何かを見ることはありませんが
これは見てからの1組である
ポップアップをうまく
スタックの先頭を手と比較していき、その後と

[注]

二人はお互いに見ることができると高い
11111を
内側に数字の文字列この
最初のと最後の1がお互いを見ることができる
ああを無視しないでください

そして、上記のこのような状況を処理する方法である
私は暴力がスタックから取り出されると思う最初の
何カウントし
、カウント数が完了した後、その後、バックスタックに
残業二つの点となるよう
、私はポイントをダウンロードした二つの点テストデータはで現れる
10のよう50万
奇妙なタイムアウトなし......
あなたはスタック構造を保つことができ
、人の高さを記録し、番号は
次の彼女があるほど背が高く、かつスタック位置にある
場合彼女と同じような状況にして、ポップアップする必要が
+ 1のようにV(個人のカウントどのように多くの)にして、爆弾

[完了コード】

[80]コード暴力スタック

#include<iostream>
#include<cstdio>
#include<stack>
using namespace std;
const int Max = 500005;
int a[Max];
stack<int>s;
int main()
{
    int n;
    cin >> n;
    for(register int i = 1;i <= n;++ i)
        cin >> a[i];
    int js = 0;
    for(register int i = 1;i <= n;++ i)
    {
        int jj = 0;
        while(!s.empty() && a[i] >= s.top())
        {
            if(a[i] == s.top())
            {
                while(!s.empty() && s.top() == a[i])
                    s.pop(),jj ++,js ++;
            }
            else
            {
                s.pop();
                js ++;
            }
        }
        if(!s.empty())
            js ++;
        while(jj --)
            s.push(a[i]);
        s.push(a[i]);
    }
    cout << js << endl;
    return 0;
}

[AC]コード

#include<iostream>
#include<cstdio>
#include<stack>
#define int long long
using namespace std;
const int Max = 500005;
struct node
{
    int h;
    int v;
}a[Max];
stack<node>s;
signed main()
{
//  freopen("music.in","r",stdin);
    int n;
    cin >> n;
    for(register int i = 1;i <= n;++ i)
        cin >> a[i].h,a[i].v = 1;
    int ans = 0;
    for(register int i = 1;i <= n;++ i)
    {
        while(!s.empty() && a[i].h > s.top().h)
        {
            ans += s.top().v;
            s.pop();
        }
        if(!s.empty() && a[i].h == s.top().h)
        {
            node qwq = s.top();
            ans += s.top().v;
            s.pop();
            if(!s.empty())
                ans ++;
            s.push((node){qwq.h,qwq.v + 1});
        }
        else
        {
            if(!s.empty())
                ans ++;
            s.push(a[i]);
        }
    }
    cout << ans << endl;
    return 0;
}

おすすめ

転載: www.cnblogs.com/acioi/p/11685599.html