沿对角线二分,并对独行独列进行优化
输入示例:
-
样例输入:
-
3 3 5 1 2 3 4 5 6 7 8 9 3 3 1 2 3 4 5 6 7 8 9 10 3 3 12 2 3 4 5 6 7 8 9 10
-
样例输出:
-
Yes No No
#include <iostream>
#include <algorithm>
#include <stdio.h>
using namespace std;
const int kMaxM = 1000;
const int kMaxN = 1000;
int array[kMaxM][kMaxN] = {0};
int m, n, k;
bool IsExists(int x1, int y1, int x2, int y2) {
// cout << x1 << " " << y1 << " " << x2 << " " << y2 << endl;
int factx = 1, facty = 1, h = min(x2 - x1, y2 - y1);
if (x1 == x2) {
factx = 0;
facty = 1;
h = y2 - y1;
} else if (y1 == y2) {
factx = 1;
facty = 0;
h = x2 - x1;
}
int l = 0, mid = 0;
bool found = false;
while (l <= h) {
mid = (l + h ) / 2;
if (array[x1 + factx * mid][y1 + facty * mid] > k) {
h = mid - 1;
} else if (array[x1 + factx * mid][y1 + facty * mid] == k) {
return true;
} else {
l = mid + 1;
}
}
if (h < 0) {
return false;
}
if (y1 + h + 1 <= n - 1) {
if (IsExists(x1, y1 + h + 1, x1 + h, y2)) {
return true;
}
}
if (x1 + h + 1 <= m - 1) {
if (IsExists(x1 + h + 1, y1, x2, y1 + h)) {
return true;
}
}
return false;
}
int main() {
while (scanf("%d %d", &m, &n) != EOF) {
scanf("%d", &k);
for (int i = 0; i < m; i++) {
for (int j = 0; j < n; j++) {
scanf("%d", &array[i][j]);
}
}
if (IsExists(0, 0, m - 1, n - 1)) {
printf("Yes\n");
} else {
printf("No\n");
}
}
return 0;
}