題解 P2085 【最小函式值】
阿新 • • 發佈:2018-12-30
題目描述
有n個函式,分別為F1,F2,...,Fn。定義Fi(x)=Aix^2+Bix+Ci (x∈N*)。給定這些Ai、Bi和Ci,請求出所有函式的所有函式值中最小的m個(如有重複的要輸出多個)。
輸入輸出格式
輸入格式:
輸入資料:第一行輸入兩個正整數n和m。以下n行每行三個正整數,其中第i行的三個數分別位Ai、Bi和Ci。Ai<=10,Bi<=100,Ci<=10 000。
輸出格式:
輸出資料:輸出將這n個函式所有可以生成的函式值排序後的前m個元素。這m個數應該輸出到一行,用空格隔開。
輸入輸出樣例
輸入樣例#1:
3 10
4 5 3
3 4 5
1 7 1
輸出樣例#1:
9 12 12 19 25 29 31 44 45 54
資料範圍
n, m <= 10000
主要思路:STL + 初中數學(實質是瞎搞)
STL就是用的優先佇列。
對於一個函式 \(f(x) = a x ^ {2} + b x + c\),我們會發現對稱軸為\(x = -\frac{b}{2a}\),所以函式\(f(x)\)在\([1, +∞)\),根據題意\(x ∈N^{*}\),可知對於每個函式\(f(x)\)都是單調遞增的。
所以我們就可以對於每個函式,先取\(x = 1\),然後再當從堆中取出這個函式的\(x = 1\)時,把\(x = 2\)扔進堆中,,,
然而,此題資料正如第一篇題解體現的那樣,資料
水
所以,我們可以為所欲為!
我直接把所有函式的前10個值放進去,WA * 9
然後,我把函式的前100個值放進去,AC……
code:
#include<iostream> #include<cstdio> #include<algorithm> #include<vector> #include<queue> using namespace std; #define go(i, j, n, k) for(int i = j; i <= n; i += k) inline int read(){ int x = 0, f = 1; char ch = getchar(); while(ch > '9' || ch < '0') { if(ch == '-') f = -f; ch = getchar(); } while(ch >= '0' && ch <= '9') { x = x * 10 + ch - '0'; ch = getchar(); } return x * f; } #define abc a[i], b[i], c[i] int a[mn], b[mn], c[mn]; inline int get_f(int x, int a, int b, int c) { return x * x * a + x * b + c; } priority_queue<int> q; int n, m; int main(){ n = read(), m = read(); go(i, 1, n, 1) { a[i] = read(), b[i] = read(), c[i] = read(); } go(i, 1, n, 1) { go(j, 1, 100, 1) { q.push(-1 * get_f(j, abc)); } } go(i, 1, m, 1) { printf("%d ", -1 * q.top()); q.pop(); } return 0; }