51Nod-1267 4つの数字の合計が0(暴力、思考)


  この質問への質問リンク\(n \ leq 1000 \)、まず最初に3つの値を直接列挙してから2つの点\(4 \)の数値を求めますが、複雑さは明らかに許容できません。次に、複雑さを軽減し続けることができます。これらの数値を前処理すると、\(n ^ 2 \)は2つの数値のグループのすべてのケースを見つけて、両端から個別に列挙できます。2つの数値の合計は0で、確かに1つは小さく、1つは大きく、 2つの列挙からの数値のすべての組み合わせを列挙すると、すべてのケースが確実に列挙されます。したがって、列挙が真ん中に達する前に、要件を満たす回答があるかどうかを判断します。

const int maxn = 1e6+10;
struct INFO {
    int a, b;
    ll sum;
    void add(int x, int y, ll z) {
        a = x, b = y, sum = z;
    }
} info[maxn];
ll arr[maxn]; int kase;
int main(void) {
    int n;
    scanf("%d", &n);
    for (int i = 0; i<n; ++i) scanf("%lld", &arr[i]);
    for (int i = 0; i<n-1; ++i)
        for (int j = i+1; j<n; ++j) 
            info[kase++].add(i, j, arr[i]+arr[j]);
    sort(info, info+kase, [](INFO x, INFO y){
        return x.sum < y.sum;
    });
    int l = 0, r = kase-1;
    while(l<r) {
        if (info[l].sum+info[r].sum == 0 && info[l].a!=info[r].a && info[l].a!=info[r].b && info[l].b!=info[r].a && info[l].b!=info[r].b) {
            printf("Yes\n");
            return 0;
        } 
        else if (info[l].sum+info[r].sum<0) ++l;
        else --r;
    }
    printf("No\n");
    return 0;

おすすめ

転載: www.cnblogs.com/shuitiangong/p/12708270.html