• ACM刷题之路(十七)二分 2019暑期集训 POJ2785


     4 Values whose Sum is 0


    题目链接传送门

    暑期集训第一弹二分、三分、尺取

    Description

    The SUM problem can be formulated as follows: given four lists A, B, C, D of integer values, compute how many quadruplet (a, b, c, d ) ∈ A x B x C x D are such that a + b + c + d = 0 . In the following, we assume that all lists have the same size n .

    Input

    The first line of the input file contains the size of the lists n (this value can be as large as 4000). We then have n lines containing four integer values (with absolute value as large as 228 ) that belong respectively to A, B, C and D .

    Output

    For each input file, your program has to write the number quadruplets whose sum is zero.

    Sample Input

    6
    -45 22 42 -16
    -41 -27 56 30
    -36 53 -37 77
    -36 30 -75 -46
    26 -38 -10 62
    -32 -54 -6 45

    Sample Output

    5

    Hint

    Sample Explanation: Indeed, the sum of the five following quadruplets is zero: (-45, -27, 42, 30), (26, 30, -10, -46), (-32, 22, 56, -46),(-32, 30, -75, 77), (-32, -54, 56, 30).


    题意:先输入一个n,表示有n行4列的数,让你每一行选出一个数字,四个数加起来刚好是0的组合数有多少种?

    注:一列中的一个元素可以被多次组合。  时限15秒

    最暴力的方法:o(n^4)

    每一列的数进行遍历,如果相加等于0让总计的cnt加加——超时

    其次:o(n^3*logn)

    对前三列遍历,对最后一列排序二分查找,如果可以找到,那么加上这个数的个数。——超时

    再次:o(n^2*log (n*n)  )

    对前两列遍历,把第三列第四列合并成数量为n*n的数组,并对其进行二分查找,如果可以找到,那么加上这个数的个数。——AC 7219ms

    最后:o(n*log (n*n*n)  )

    对前一列遍历,把第二列第三列第四列合并成数量为n*n*n的数组,并对其进行二分查找,如果可以找到,那么加上这个数的个数。——爆内存

    所以最后AC的方法是第三种,代码如下:

    其中 inline bool scan_d(int& num) 是输入挂 当输入数据较多的时候能明显减少输入耗时

    inline是内联函数 C++ 对于多次调用的函数,可以使用内联,减低时间消耗,增加主函数的内存消耗。

    因为用的是VS2019 ,scanf要报错,所以使用scanf_s函数,功能在本题中一样

    基础二分题,主要采用了用空间换时间的思想

    #include<iostream>
    #include<algorithm>
    #include<cstring>
    #include<vector>
    using namespace std;
    inline bool scan_d(int& num)//输入挂
    {
    	char in; bool IsN = false;
    	in = getchar();
    	if (in == EOF) return false;
    	while (in != '-' && (in<'0' || in>'9')) in = getchar();
    	if (in == '-') { IsN = true; num = 0; }
    	else num = in - '0';
    	while (in = getchar(), in >= '0' && in <= '9')
    	{
    		num *= 10, num += in - '0';
    	}
    	if (IsN) num = -num;
    	return true;
    }
    int main()
    {
    	int n;
    	scanf_s("%d", &n);
    	vector<int>v[5];
    	for (int i = 0; i < n; i++)
    	{
    		for (int j = 0; j < 4; j++) {
    			int num;
    			scanf_s("%d", &num);
    			v[j].push_back(num);
    		}
    	}
    	for (int i = 0; i < n; i++) {
    		for (int j = 0; j < n; j++) {
    			v[4].push_back(v[2][i] + v[3][j]);//把第三列第四列合并放入v[4]
    		}
    	}
    	int cnt = 0;
    	sort(v[4].begin(), v[4].end());
    	for (int i = 0; i < n; i++)
    	{
    		for (int j = 0; j < n; ++j)
    		{
    			int ans = 0 - v[0][i] - v[1][j];//真正需要的值
    			int index = lower_bound(v[4].begin(), v[4].end(), ans) - v[4].begin();
    			//index找大于等于ans的首位置 下行同理
    			if (lower_bound(v[4].begin(), v[4].end(), ans) != v[4].end() && v[4][index] == ans)
    			{//该函数找不到返回end(); cnt加上找到该值的数量
    				int indexx = lower_bound(v[4].begin(), v[4].end(), ans + 1) - v[4].begin();
    				cnt += indexx - index;
    			}
    		}
    	}
    	printf("%d
    ", cnt);
    	return 0;
    }
  • 相关阅读:
    c# 获取iis地址
    c# 导入导出Excel
    ffmpeg 转成MP3采样率8000
    c# 百度api语音识别
    c# 文件转换成base64
    js截取文件的名称
    js checkbox获取选中的值
    js base64位和c# Base64位转换
    笨方法学Python——习题16
    Python学习问题
  • 原文地址:https://www.cnblogs.com/yyzwz/p/13393264.html
Copyright © 2020-2023  润新知