沿对角线二分,并对独行独列进行优化

输入示例:

 

样例输入:
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;
}