t1準確率
【題目描述】
你是乙個驍勇善戰、日刷百題的oier. 今天你已經在你oj 上提交了y 次,其中x次是正確的,這時,你的準確率是x/y.
注意:本題中,0/1 和1/1 都是既約分數.
【輸入格式】
從檔案rate.in 中讀入資料。
輸入第一行包含乙個正整數t (t <= 5 * 10 ^ 5),表示資料組數.
接下來t 行,每行4 個整數x, y, p, q (0 <= x <= y <= 10 ^ 9; 0 <= p <= q <= 10 ^ 9; y > 0; q > 0),含義如題所述.
【輸出格式】
輸出到檔案rate.out 中。
輸出t 行,每行乙個整數,表示使正確率達到p/q 所需最小提交次數;若無法達到,輸出-1.
【樣例1 輸入】
43 10 1 2
7 14 3 8
20 70 2 7
5 6 1 1
【樣例1 輸出】410
0-1【樣例1 解釋】
第一組資料中,你需要進行4 次正確的提交,使準確率達到7/14,即1/2;
第二組資料中,你需要進行2 次正確的提交,8 次錯誤的提交,使準確率變為9/24,即3/8;
第三組資料中,你無需進行任何提交,因為你的準確率已為20/70,即2/7;
第四組資料中,在原有的提交中已有一次錯誤提交,準確率不可能達到1.
【樣例2】
見選手目錄下的rate/rate2.in 與rate/rate2.ans。
【子任務】
對於30% 的資料,t = 1;
對於另30% 的資料,t <= 1000.
以上兩部分資料中,各有50% 的資料保證x, y, p, q <= 10 ^ 4.
題意很明了,然後別想偏了……
首先不要把x, y約分要不然答案肯定不對,這是挺顯然的。
然後不要把這題想成數論的不定方程,雖然設完正確提交和錯誤提交後化簡一下確實很像不定方程,然而會有負數,而且這塊我有些地方還是不太懂,所以肯定不是這個做法……
實際上,這不過是一道初中不等式,只要將p, q同時擴大n倍後,滿足n * p >= x && n * q >= y就行了。
1 #include2 #include3 #include4 #include5 #include6 #include7 #include8 #include9 #include10 #include11using
namespace
std;
12#define enter printf("\n")
13#define space printf(" ")
14#define mem(a) memset(a, 0, sizeof(a))
15 typedef long
long
ll;16 typedef double
db;17
const
int inf = 0x3f3f3f3f;18
const
int eps = 1e-8;19
//const int maxn = ;
20inline ll read()
2125
while
(isdigit(ch))
2629
if(last == '
-') ans = -ans;
30return
ans;31}
32 inline void
write(ll x)
3338
39int
t;40
41int main() //
**就這麼短……
4256}57
return0;
58 }
t2 模擬賽
【題目描述】
你很快地完成了所有的題目,並且使準確率達到了p/q,於是開始無所事事. 老師看見了,對你說:「你今天做的題夠多的了,別再做了. 我們接下來k 天每天都要模擬,我這裡有很多題,你去選一些題目編k 場模擬賽吧. 」老師將所有題目都編了序號,還給你了n 種出題方案(所有方案兩兩不同). 每種出題方案選擇所有編號屬於[l; r] 的題目,作為一天的試題. 現在,你需要選出k 種出題方案(乙個方案只能選取一次),分別對應k 天的模擬賽. 老師非常強調複習的重要性,因此希望有一些題目每天都出現在模擬賽當中,你需要最大化每天都出現的題目的數量.
【輸入格式】
從檔案exam.in 中讀入資料。
輸入第一行包含兩個正整數n; k (1 <= k <= n <= 3 * 10 ^ 5),分別為出題方案數和模擬賽天數.
接下來n 行,每行兩個整數l; r (-10 ^ 9 <= l <= r <= 10 ^ 9),表示乙個出題方案(保證所有方案兩兩不同).
【輸出格式】
輸出到檔案exam.out 中。
輸出乙個非負整數,表示每天都出現的題目的數量的最大值.
【樣例1 輸入】
4 21 100
40 70
120 130
125 180
【樣例1 輸出】
31【樣例1 解釋】
選擇前兩種方案,編號為[40; 70] 的題目在兩種方案中均出現,共有31 道題.
【樣例2 輸入】
3 21 12
15 20
25 30
【樣例2 輸出】
0【樣例2 解釋】
所有給出的方案互不相交,所以答案為0.
【子任務】
對10% 的資料,k = n;
對另20% 的資料,k = 2;
對另20% 的資料,1 <= k <= n <= 20;
其餘5 組資料,n = 10 ^ 2, 10 ^ 3, 10 ^ 4, 10 ^ 5, 3 * 10 ^ 5.
簡單來說,就是讓你從給定的n個區間中找出k個區間,使這k個區間的公共部分長度最大。
很容易想到,在所選的區間中,公共部分的長度是由最大的左端點的和最小的右端點控制的。那麼如果我們先把所有區間按左端點排序,然後列舉左端點,那麼控制公共區間長度的就是當前的左端點和最小的右端點。因此我們只要想辦法維護所選區間的右端點就行了。
o(n ^ 2)的做法是,對於每乙個區間,從左端點比他小的區間中選出右端點最大的 k-1 個區間,其中右端點第k-1大的就是當前公共區間的右端點。
然後我們就可以用乙個堆優化選取這個右端點的過程,把所選的區間的右端點都放到小根堆裡,當堆中元素大於k個或是根的右端點比當前左端點小,就刪除根,然後當列舉到第i個區間時的答案就是 q.top() - a[i].l +1,並嘗試用這個更新答案。
1 #include2 #include3 #include4 #include5 #include6 #include7 #include8 #include9 #include10 #include11 #include12using
namespace
std;
13#define enter printf("\n")
14#define space printf(" ")
15#define mem(a) memset(a, 0, sizeof(a))
16 typedef long
long
ll;17 typedef double
db;18
const
int inf = 0x3f3f3f3f;19
const
int eps = 1e-8;20
const
int maxn = 3e5 + 5;21
inline ll read()
2226
while
(isdigit(ch))
2730
if(last == '
-') ans = -ans;
31return
ans;32}
33 inline void
write(ll x)
3439
40int
n, k;
41struct
node
4248
}a[maxn];
4950
51struct que //
忘了優先佇列的小根堆寫法……
5258
};59 priority_queueq;
60int cnt = 0, ans = 0;61
62int
main()
6368 sort(a + 1, a + n + 1
);69
for(int i = 1; i <= n; ++i)
70); cnt++;
72if(cnt > k)
73while(!q.empty() && a[i].l > q.top().l)
74if(cnt == k) ans = max(ans, q.top().l - a[i].l + 1
);75}76
write(ans); enter;
77return0;
78 }
t3還不會呀……(小聲)
2018寒假福州集訓記Day1
哦 今天上午直接一波考試。之前1個月都在準備期末考試,資訊書都沒翻過,考試前臨時抱佛腳,然而並沒啥卵用。好了不談了,說說題目吧。t1是一道dp題目 我考完試才知道,考試的時候我也有想過可能與遞推有關 題目給的樣例剛好是兩種極端的情況,一種是每行語句下面都加乙個printf再編譯一遍,另一種是一直二分...
暑假集訓day1 水題 乘法最大
題目大意 有乙個長度為n的字串,要求用k個乘號將其分成k 1個部分,求各個部分相乘的最大值 輸入 第一行輸入n和k,第二行輸入乙個長度為n的字串 演算法分析 1.這個題只是乙個簡單的dp 甚至連區間dp都不是 2.dp i j 表示前i個數字裡面用了j個乘號,而列舉的狀態k表示前k個數字用了j 1個...
湖南集訓Day1
難度不斷網 斷網 卡特蘭數取模 由於資料範圍小,直接做。考試時斷網。忘記卡特蘭數公式,推錯了只有5分。數學公式要記別每次都現用現搜!include include include using namespace std int f 1007 int n,m,ans intmain 模數較小是乙個坑點...