您的位置:首页 > 编程语言 > C语言/C++

矩阵

2016-06-20 00:25 204 查看

题目描述

给你一个 N 行 M 列的矩阵,其中第 i 行,第 j 列的元素 Aij = 2 * i * j + 3 * i + 3 * j + 3。求第 k 小的数字。

输入

一行 3 个整数 N M k。

0 < N, M < 1e5

0 < k < N * M + 1

输出

输出第 k 小的数字。

样例输入

2 3 3

样例输出

16

#include <iostream>

using namespace std;

int main() {
long long a, b, n;
cin >> a >> b >> n;
long long s1 = 2ll*1ll*1ll+3ll*1ll+3ll*1ll+3ll;
long long s2 = 2ll*a*b+3ll*a+3ll*b+3ll;
long long temp1, temp2, num1, num2, b1;
long long s, k;
long long i, j;

while(1){
s = (s1 + s2 + 1ll)/2ll;
num1 = 0ll, num2 = 0ll;
b1 = b;
for (i = 1ll; i <= a; ++i) {
temp1 = 0ll, temp2 = 0ll;
for (j = b1; j >= 1ll; --j) {
k  = 2ll*i*j+3ll*i+3ll*j+3ll;
if (s > k) {
temp1 += j;
break;
}else if (s == k) {
temp2++;
}
}
if (temp1 == 0ll && temp2 == 0ll) {
break;
}
num1 += temp1;
num2 += temp2;
if(num1 >= n) {
break;
}
b1 = temp1;
}
if (num1 < n && (num1+num2) >= n){
cout << s << endl;
break;
} else if (num1 > n) {
s2 = s;
continue;
} else if(num1 == n) {
s2 = s-1ll;
} else {
s1 = s;
continue;
}
}
return 0;
}


看到题目,我内心是崩溃的,首先我去找规律(这根本找不到什么规律,显然失败了),大神教我用二分法。二分法只是一个最大的方向,其实在获得比目标数小的个数的时候,必须要很彻底的剪枝(剪枝完,那得出结果的速度)。这道题也可以用递归的方法(笔者之前用递归内存超了,不开心)总之花了不好时间。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  c语言 算法