羅区の問題解決--P1114:「非常に男性と女性」プログラム

関連するトピック

トピックリンク

羅バレー、https://www.luogu.com.cn/problem/P1114

総旅客ニンニク、https://nanti.jisuanke.com/t/T1853

私のOJ、http://47.110.135.197/problem.php?id=5252

タイトル説明

最近、年の初めXXXマッチング問題に取り組んで子どもたちは、様々な実験や推論によるクラスメートが、彼は実際の戦闘経験の多数をマスター(だけのパートナーを踊り、考えすぎ)。例えばもっと仲良しのようです、彼の観察によると、同様の高さ。

ハロウィーンは、近づいているXXX大規模な学校で「非常に男性と女性の」マッチング活動を計画する準備ができて。イベントの参加者のために、XXX彼らは選択肢の独自の方法を持っています。彼は、男性と女性の数と同じ数を選択したいと考えていると、一部の人は背が高いと近くにあります。この選択を実装するには非常に簡単です。彼は、行の高さに応じて、すべての学校を聞かせて、その後、これらの人々は、男性と女性の数が等しくなるように、いくつかの連続した個体から選択します。、イベントもっと楽しくするためにXXX、もちろん彼はできるだけ多くの人を選出するという希望を。彼は人々の最大数を選択することができることを彼に伝えるためにプログラムを作成してください。

入力形式

最初の行は、正の整数n、学校の代表者の数があります。N≤100000

第二行は、nの番号がスペースで区切られ、これらの数だけ0が女の子を表し、少年を表し、0又は1であることができます。

出力フォーマット

出力非負の整数。この数は、長さの入力データシーケンスの中で最長の男性と女性の周期に等しい示します。

男性と女性のシーケンス同じ番号が存在しない場合は、出力0。

サンプル入力

9
0 1 0 0 0 1 1 0 0

サンプル出力

6

トピック分析

問題の意味の分析

1と0の同じ数を含む配列の列の長さnの数、最長シーケンス[L、R]を見つけます。これは何を意味するのでしょうか?私たちは考えます。アレイアレイ0及び1のみを二種類。[L、R]は要素が前に持っている場合、X仮定  \ sum_ {I = L} ^ {R} a_iを 値はどのくらいであるべきですか?スマートは、あなたはすぐには考えていない、これがなければなりません  \ FRAC {X} {2}今は最初の計算とプレフィックスへのすべての我々のニーズの反映すべきです。

サンプルデータ解析

入力サンプルデータ[010001100]であり、そして、対応するプレフィックスは[0011112333]です。私たちがしたいので、同じ質問が男の子と女の子、結果は偶数でなければならないことを意味を尋ねました。ナインサンプルデータ、わずか8の最大長。我々はサブシーケンスを見つけることができるかどうか2,4,6,8-アイデアがあります。のは、暴力のプロセスは、コンピューティング何をシミュレートするために、テーブルを描画してみましょう。

リットル R 人数 I [R] -sum [I-1] ラインで? リマーク
2 9 8 3-0 = 3  
1 8 8 3-0 = 3  
4 9 6 3-1 = 2  
3 8 6 3-1 = 2  
2 7 6 3-0 = 3 図6は、組成物を確認する必要はありません4

上記表に示すように、最長の最終シーケンス6。

データ分析の範囲

ようトピックの範囲によって提供されたデータによれば、我々は、Nの最大値は10000である知ることができる  O(N ^ {2}) アルゴリズムの複雑さを通過する方法はありません。少量のデータのためには、我々はかろうじてでき、上記のアイデアを参照して、スティックを引くことができます。最も不利な原則によると、我々は、アルゴリズムの複雑さが変更されていないことを知ることができる  O(\ FRAC {1} {2} N ^ {2})(実際にはそのような複雑さが)。

アルゴリズムの最適化

上記O(nlogn)最適化アルゴリズムであるO(n)はできますか?

私たちは、生データの簡単な処理を必要とします。元のデータは、0は女の子で表される、男の子、すなわち、我々は、対称先の、1で示されるで示される-1の女の子は、男の子は男の子と女の子の限り対、およびゼロ対応する、1で表されます。我々はまた、次のサンプルデータを用いて分析しました:

いいえ。 1 2 3 4 5 6 7 8 9
生データ 0 1 0 0 0 1 1 0 0
変更されたデータ -1 1 -1 -1 -1 1 1 -1 -1
プレフィックスと -1 0 -1 -2 -3 -2 -1 -2 -3

データが変更された後、それが仮定される[L、R] Xは前の要素を持っている、この同じくらいの男の子と女の子の数がバインドされている場合\ sum_ {I = L} ^ {R} a_iを、すなわち和[R] =和[L -1]。

したがって、我々はまた、プレフィックスを計算し、上記のように、我々は次のハッシュテーブルを取得することができ、ハッシュテーブルを確立します。

上記のように、データ値の最初の列は、ハッシュテーブル、対応する接頭辞インデックスにハッシュ値に戻りました。当社は、以下の情報を見ることができます:

1、プレフィックスのみとデータが0であるので、確かに組み合わせて、男性と女性で構成さではありません。

2三のプレフィックスがあり、データは-1、そして、6は男性と女性の個人の組み合わせを示し、最小1、最大プレフィクスおよび7のインデックス付き文字プレフィックスは1に対応し、すなわち元のデータ配列の添字2~7に、構成することができます00011、3人の男性と3人の女性です。

3三のプレフィックスがあり、データが-2、最小添字プレフィックス及び4、及び8の添字プレフィックス最大、4は0に対応する、すなわち、元のデータ配列インデックス5~8に、構成することができる男性と女性の個人の組み合わせを示しています110、2人の男性と2人の女性です。

図4に示すように、2つのプレフィックス、および-3データ、プレフィックスと5の最小屈折率、及び9最大添字プレフィックスがあり、図4は、男性と女性個体の組合せが対応する、すなわち、元のデータ配列が、6~9の添字、構成することができることを示し2人の男性と2人の女性である1100。

AC参照コード

暴力の削減を実現スティック

データの量が1E5を超えた場合、このアルゴリズムは無力であると推定しています。一部のTLEを取得します。

#include <cstdio>
using namespace std;

const int MAXN = 1e5+4;
int nums[MAXN];//原始数据
int qzh[MAXN];//前缀和

int main() {
    int n;
    scanf("%d", &n);

    for (int i=1; i<=n; i++) {
        scanf("%d", &nums[i]);
        qzh[i] = qzh[i-1]+nums[i];
    }

    /*
    i表示构造长度
    j表示起点
     */
    int m= (1==n%2) ? n-1 : n;
    for (int i=m; i>=2; i-=2) {
        //n,n/2,n/4,...,4,2 的长度进行验证
        for (int j=n; j-i>=0; j--) {
            if ((qzh[j]-qzh[j-i])*2==i) {
                printf("%d\n", i);
                return 0;
            }
        }
    }
    printf("0\n");

    return 0;
}

最適化アルゴリズム

私たちは、内部unordered_mapは、ハッシュテーブルを使用して達成知っているので、我々は、STLのこのタイプを使用することができます。

#include <cstdio>
#include <unordered_map>

using namespace std;

const int MAXN = 1e5+4;
int nums[MAXN];//前缀和

int main() {
    int n;
    scanf("%d", &n);

    unordered_map<int, int> hash;
    hash[0] = 0;//特例处理
    int ans = 0;
    for (int i=1; i<=n; i++) {
        scanf("%d", &nums[i]);
        if (0==nums[i]) {
            nums[i] = -1;
        }
        nums[i] += nums[i-1];//构造前缀和

        if (hash.find(nums[i]) == hash.end()) {
            //第一次出现,增加到哈希表中
            hash[nums[i]] = i;
        } else if (i-hash[nums[i]]>0 && i-hash[nums[i]]>ans) {
            //出现过
            ans = i-hash[nums[i]];
        }
    }

    printf("%d\n", ans);

    return 0;
}

使用unordered_map、いくつかの具体的な例に注意を払います。入力された場合

4
1 0 0 1

 

 

公開された235元の記事 ウォンの賞賛289 ビュー107万+

おすすめ

転載: blog.csdn.net/justidle/article/details/104848187