码迷,mamicode.com
首页 > 其他好文 > 详细

poj 2758 多重部分和

时间:2015-05-29 14:07:25      阅读:143      评论:0      收藏:0      [点我收藏+]

标签:

  • 题意:给你一个n行4列的矩阵,从每列选择一个数字,问这四个数字加起来为0的数字组合有多少个?
  • 思路:暴力O(n4)超时,只有把前两个数字的所有和枚举出来(O(n2)),然后排序(O(nlogn)),最后枚举最后两数的所有组合,每一个组合用二分查找已经排序好的前两个数字组合(O(n2logn)),故总的复杂度是:O(n2logn)
    代码:
#include <set>
#include <map>
#include <cmath>
#include <stack>
#include <queue>
#include <string>
#include <vector>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
typedef long long int LL;
const int M = 4009,INF = 0x3fffffff;
int n, a[M], b[M], c[M], d[M];
int A[M * M], B[M * M];

int doit(int x, int step) {
    int l = 0, r = step , mid = -1, ans = 0;
    while(l < r) {
        mid = (l + r) / 2;
        if(B[mid] == x) {
            for(int i = mid - 1; i >= 0; i--) {
                if(B[i] != x) break;
                ans++;
            }
            for(int i = mid; i < step; i++) {
                if(B[i] != x) break;
                ans++;
            }
            break;
        }
        if(B[mid] < x) l = mid + 1;
        else r = mid;
    }
    return ans;
}

int main(void) {
    //problem:poj 2785 , address:  http://poj.org/problem?id=2785             
    while(cin >> n) {
        int step = 0;
        for(int i = 0; i < n; i++) cin >> a[i] >> b[i] >> c[i] >> d[i];
        for(int i = 0; i < n; i++) {
            for(int j = 0; j < n; j++) {
                A[step] = a[i] + b[j];
                B[step++] = c[i] + d[j];
            }
        }
        sort(B, B + step);
        int ans = 0;
        for(int i = 0; i < step; i++) {
            ans += doit(-A[i], step);
        }
        cout << ans << endl;
    }
    return 0;
}

poj 2758 多重部分和

标签:

原文地址:http://blog.csdn.net/jibancanyang/article/details/46228355

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!