AcWing 1221. 四平方和 (哈希 or 二分)

Problem

这个题暴力需要至少三层循环,每层大概106严重超时。
优化方法是将四个数分成两拨运算,例如abcd是答案的四个数,先算出a和b,然后temp = n - a - b
再运行循环找出能凑出temp 的c和d,具体寄存方法有二分法和哈希表。

方法一:二分法 (N2logN)

C++描述:

#include <cstring>
#include <iostream>
#include <algorithm>
#include <cmath>

using namespace std;

const int N = 2500010;

struct Sum
{
    int s, c, d;
    bool operator< (const Sum &t)const
    {
        if (s != t.s) return s < t.s;
        if (c != t.c) return c < t.c;
        return d < t.d;
    }
}sum[N];

int n, m;

int main()
{
    cin >> n;

    for (int c = 0; c * c <= n; c ++ )
        for (int d = c; c * c + d * d <= n; d ++ )
            sum[m ++ ] = {c * c + d * d, c, d};

    sort(sum, sum + m);

    for (int a = 0; a * a <= n; a ++ )
        for (int b = 0; a * a + b * b <= n; b ++ )
        {
            int t = n - a * a - b * b;
            int l = 0, r = m - 1;
            while (l < r)
            {
                int mid = l + r >> 1;
                if (sum[mid].s >= t) r = mid;
                else l = mid + 1;
            }
            if (sum[l].s == t)
            {
                printf("%d %d %d %d\n", a, b, sum[l].c, sum[l].d);
                return 0;
            }
        }

    return 0;
}

方法二:哈希表 (logN)

Java 描述:

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.util.Arrays;
import java.util.HashMap;

public class Main {
    static BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
    static PrintWriter pw = new PrintWriter(System.out);
    static int n;
    static HashMap<Integer, int[]> map = new HashMap<>();

    public static void main(String[] args) throws Exception {
        n = Integer.parseInt(br.readLine());

        for (int i = 0; i * i <= n; i++)
            for (int j = 0; j * j + i * i <= n; j++)
                map.put(i * i + j * j, new int[]{i, j});
        boolean flag = true;
        for (int i = 0; i * i <= n && flag; i++)
            for (int j = 0; j * j + i * i <= n && flag; j++) {
                int t = n - j * j - i * i;
                if (map.containsKey(t)) {
                    int tmp[] = map.get(t);
                    int res[] = {tmp[0], tmp[1], i, j};
                    Arrays.sort(res);
                    for (int k = 0; k < res.length; k++) pw.print(res[k] + " ");
                    flag = false;
                }
            }


        pw.flush();
        pw.close();
        br.close();

    }
}

发布了167 篇原创文章 · 获赞 3 · 访问量 3441

猜你喜欢

转载自blog.csdn.net/qq_43515011/article/details/104144424
今日推荐