time limit per test
1 second
memory limit per test
256 megabytes
input
standard input
output
standard output
Bizon the Champion isn't just charming, he also is very smart.
While some of us were learning the multiplication table, Bizon the Champion had fun in his own manner. Bizon the Champion painted ann?×?m multiplication table, where the element on the intersection of the i-th row and j-th column equals i·j (the rows and columns of the table are numbered starting from 1). Then he was asked: what number in the table is the k-th largest number? Bizon the Champion always answered correctly and immediately. Can you repeat his success?
Consider the given multiplication table. If you write out all n·m numbers from the table in the non-decreasing order, then the k-th number you write out is called the k-th largest number.
Input
The single line contains integers n, m and k (1?≤?n,?m?≤?5·105; 1?≤?k?≤?n·m).
Output
Print the k-th largest number in a n?×?m multiplication table.
Sample test(s)
input
2 2 2
output
input
2 3 4
output
input
1 10 5
output
Note
A 2?×?3 multiplication table looks like this:
1 2 32 4 6
題目意思是,從一個n*m的乘法表(不要問我乘法表是什么)中選出第k小數(相同的數字會計算多次)。
比如樣例 2 3 4
乘法表為
1 2 3
2 3 4
非減序列是:1, 2, 2, 3, 3, 4。第4個數字是3,所以輸出3。
一開始我想到的是搜索,從n*m開始搜索,后來發現狀態實在太多而且即便是搜索,時間復雜度是O(N * M)。
正確的解法是二分。二分答案(邊界是[1, n * m]),然后在乘法表中去找比他小的數。因為乘法表是一個有規律的數表,所以針對每一列直接O(1)計算即可,總共計算N次。
總的時間復雜度是O(N * 2 * log(N))。
/*****************************************************************************# COPYRIGHT NOTICE# Copyright (c) 2014 All rights reserved# ----Stay Hungry Stay Foolish----## @author :Shen# @name :D# @file :D.cpp# @date :2014/07/17 22:47# @algorithm :Binary Search******************************************************************************///#pragma GCC optimize ("O2")//#pragma comment(linker, "/STACK:1024000000,1024000000")#includeusing namespace std;template inline bool updateMin(T& a, T b){ return a > b ? a = b, 1: 0; }template inline bool updateMax(T& a, T b){ return a < b ? a = b, 1: 0; }typedef long long int64;int64 n, m, k;bool check(int64 x){ int64 res = 0; for (int i = 1; i <= n; i++) { int64 tmp = min(i * m, x); res += tmp / i; } return res < k;}// 從小往大 計數,第k個int64 BinarySearch(int64 l, int64 r){ while (l < r) { int64 mid = (l + r) / 2; //cout << l << " " << mid << " " << r << endl; //cout << "check result: " << check(mid); if (check(mid)) l = mid + 1; else r = mid; //system("pause"); } return r;}int main(){ cin >> n >> m >> k; int64 Right = n * m, Left = 1; int64 ans = BinarySearch(Left, Right); cout << ans; return 0;}
聲明:本網頁內容旨在傳播知識,若有侵權等問題請及時與本網聯系,我們將在第一時間刪除處理。TEL:177 7030 7066 E-MAIL:11247931@qq.com