Skip to content

12109: 【原2109】二次方程

题目

题目描述

author: tomtao26 原OJ链接:https://acm.sjtu.edu.cn/OnlineJudge-old/problem/2109

Description

小C最近正在研究二次方程,遇到了一些问题,希望你能帮他解决。现在有\(N\)个数,小C想知道,这\(N\)个数中有多少数作为\(a\),才能使给定\(b\),\(c\),对于\(ax^2 + bx + c = 0\)有实数解。

Input Format

一个整数\(N\),表示有\(N\)个数。

接下来\(N\)行是这\(N\)个数\(a_i\) (\( a_i > 0\))。

随后一个整数\(K\),表示有\(K\)个询问问题的\((b,c)\)对。

接下来\(k\)行,表示一个询问,每行两个数,分别是\(b\)和\(c\)(\(b,c > 0\))。

Output Format

每一行对于每个给定的询问,给出一个答案\(k_i\),表示有对于第\(i\)个询问的\((b,c)\)有\(k_i\)个数满足要求。

Sample Input

3
1
2
3
2
6 2
3 2

Sample Output

3
1

Specification

\( N \leq 100000\); \( K \leq 10000\); \( b, c \leq 10000\); \( a_i \leq 100000\);

为方便起见,这\(N\)个数是已经从小到大排好序的。

BugenZhao's solution

//
// Created by BugenZhao on 2019/3/17.
//
// 线性探测

#include <iostream>

using namespace std;

static const auto _____ = []() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    return nullptr;
}();

int main() {
    int N;
    cin >> N;
    auto a = new int[N];
    int tmp;
    for (int i = 0; i < N; ++i) {
        cin >> tmp;
        a[i] = (-4) * tmp;
    }
    int K;
    cin >> K;
    int b, c;
    for (int j = 0; j < K; ++j) {
        cin >> b >> c;
        int count = 0;
        int b2 = b * b;
        for (int i = 0; i < N; ++i) {
            if (b2 + a[i] * c >= 0) {
                ++count;
            } else {
                break;
            }
        }
        cout << count << endl;
    }
    delete[] a;
    return 0;
}

FineArtz's solution

/* 二次方程 */
#include <iostream>
#include <cmath>
using namespace std;

int a[100005] = {0};

int search(int low, int high, double dt){
    int l = low, h = high, m = (l + h) / 2;
    while (h > l){
        m = (l + h) / 2;
        if (abs(a[m] - dt) < 10e-6) return m + 1;
        if (a[m] < dt)
            l = m + 1;
        else
            h = m - 1;
    }
    return l;
}

int main(){
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    int n, k;
    cin >> n;
    for (int i = 1; i <= n; ++i) cin >> a[i];
    cin >> k;
    for (int i = 1; i <= k; ++i){
        int b, c, cnt = 0;
        cin >> b >> c;
        if (c == 0) cnt = n;
        else{
            double dt = b * b * 1.0 / 4 / c;
            if (a[1] > dt) cnt = 0;
            else cnt = search(1, n, dt);
        }
        cout << cnt << endl;
    }
    return 0;
}

ligongzzz's solution

#include "iostream"
#include "cmath"
#include "cstdio"
using namespace std;

int ai[100009] = { 0 };

int mid_find(int left, int right, int val) {
    if (left == right) {
        if (ai[left] <= val)
            return left;
        else return left - 1;
    }
    int mid = (left + right) >> 1;
    if (ai[mid] == val)
        return mid;
    else if (ai[mid] < val) {
        return mid_find(mid + 1, right, val);
    }
    else {
        return mid_find(left, mid - 1, val);
    }
}

int main() {
    int N;
    scanf("%d", &N);
    for (int i = 0; i < N; ++i)
        scanf("%d", &ai[i]);

    int K;
    scanf("%d", &K);
    for (int i = 0; i < K; ++i) {
        int b, c;
        scanf("%d %d", &b, &c);

        printf("%d\n", mid_find(0, N - 1, b * b / (4 * c)) + 1);
    }

    return 0;
}

LuminousXLB's solution

// 2109. 二次方程
// #423574 正确 / 分数100 / 时间1123ms / 内存11372kb
#include <cstdio>

bool delta(int a, int b2, int c) {
    int delta = b2 - 4 * a * c;

    return delta >= 0;
}


int main(int argc, char const *argv[]) {
    int N;

    scanf("%d", &N);
    int *num = new int[N];
    for (int i = 0; i < N; i++) {
        scanf("%d", num + i);
    }

    int K, b, c;
    scanf("%d", &K);
    for (int i = 0; i < K; i++) {
        scanf("%d %d", &b, &c);
        b = b * b;
        for (int j = 0; j < N; j++) {
            if (!delta(num[j], b, c)) {
                printf("%d\n", j);
                break;
            } else if (j == N - 1) {
                printf("%d\n", N);
            }
        }
    }

    delete[] num;
    return 0;
}

q4x3's solution

/**
 * 二分
 * 找到不大于tmp的最大a,a[lo - 1] (a[lo]为比tmp大的最小a)
 * 故lo个a可以
 **/
#include <iostream>

using namespace std;

int N, K, lo, hi, mi;
double a[100233];

int main() {
    cin >> N;
    for(int i = 0;i < N;++ i) {
        scanf("%lf", &a[i]);
    }
    cin >> K;
    for(int i = 0;i < K;++ i) {
        double b, c;
        scanf("%lf%lf", &b, &c);
        double tmp = b * b / (4 * c);
        lo = 0; hi = N;
        while(lo < hi) {
            mi = (lo + hi) >> 1;
            if (tmp < a[mi]) {
                hi = mi;
            } else {
                lo = mi + 1;
            }
        }
        printf("%d\n", lo);
    }
    return 0;
}

skyzh's solution

#include <iostream>
#include <iomanip>
#include <algorithm>
using namespace std;

double D[100000];

int main() {
    int N, K;
    double b, c;
    scanf("%d", &N);
    for (int i = 0; i < N; i++) {
        scanf("%lf", &D[i]);
    }
    scanf("%d", &K);
    for (int i = 0; i < K; i++) {
        scanf("%lf%lf", &b, &c);
        double _s = b * b / 4.0 / c;
        int pos = upper_bound(D, D + N, _s) - D;
        printf("%d\n", pos);
    }
    return 0;
}

victrid's solution

#include <iostream>
#include <stdio.h>

using namespace std;

int bp(int N, int* spis, int poisk) {
    int min = 0, max = N - 1, mid;
    if (poisk >= spis[max])
        return N;
    if (poisk < spis[min])
        return 0;
    while (min <= max) {
        mid = (min + max) / 2;
        if (poisk == spis[mid])
            return mid + 1;
        else if (poisk < spis[mid])
            max = mid - 1;
        else
            min = mid + 1;
    }
    return 0;
}
int main() {
    //* scanf and printf to reduce time
    int N, k, b, c;
    cin >> N;
    int* spis = new int[N];
    for (int i = 0; i < N; i++)
        scanf("%d", spis + i);
    scanf("%d", &k);
    int* otv = new int[k];
    for (int i = 0; i < k; i++) {
        scanf("%d %d", &b, &c);
        otv[i] = bp(N, spis, (b * b / c / 4));
    }
    for (int i = 0; i < k; i++) {
        if (i)
            printf("\n");
        printf("%d", otv[i]);
    }
    return 0;
}