题目描述: ios
在一个二维数组中,每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序。请完成一个函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数。数组
输入:函数
输入可能包含多个测试样例,对于每一个测试案例,测试
输入的第一行为两个整数m和n(1<=m,n<=1000):表明将要输入的矩阵的行数和列数。spa
输入的第二行包括一个整数t(1<=t<=1000000):表明要查找的数字。code
接下来的m行,每行有n个数,表明题目所给出的m行n列的矩阵(矩阵如题目描述所示,每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序。排序
输出:内存
对应每一个测试案例,ci
输出”Yes”表明在二维数组中找到了数字t。input
输出”No”表明在二维数组中没有找到数字t。
第一反应深度优先遍历
#include <cstring> #include <iostream> #include <vector> #include <stack> #include <algorithm> #include <cstring> #include <stack> using namespace std; enum{ WHITE = 0, GRAY, BLACK }; struct map_item{ int val; int color; }; #define MAX_ROW 1100 #define MAX_COL 1100 struct map_item map_table[MAX_ROW][MAX_COL]; struct pos{ int row; int col; }; stack<struct pos> pos_store; int m, n, key; bool find_key; #define CLR(a) memset(a, 0, sizeof(a)) #define CHECK_VAL(pos, kval) ( (map_table[pos.row][pos.col].val == kval ) ? (0) : (map_table[pos.row][pos.col].val > kval ? -1 : 1)) #define SET_COLOR(pos, kcolor) ( map_table[pos.row][pos.col].color = kcolor ) #define CHECK_COLOR(pos, kcolor) ( map_table[pos.row][pos.col].color == kcolor ) #define CHECK_RANGE(pos, max_row, max_col) ( !((pos.row < 1) || (pos.row > max_row) || (pos.col < 1) || (pos.col > max_col))) #define GOTO_POS(pos) do{ \ if(CHECK_COLOR(pos, WHITE) && CHECK_RANGE(pos, m, n)){\ SET_COLOR(pos, GRAY);\ pos_store.push(pos);\ }\ }while(0) #define LEFT_POS(pos) do{\ pos_store.pop();\ SET_COLOR(curr_pos, BLACK);\ }while(0) #define DBG_POS(pos) do{\ cout << "pos[" << pos.row << "]["<< pos.col << "]" << endl;\ cout << "val:" << map_table[pos.row][pos.col].val << endl;\ cout << "color:" << map_table[pos.row][pos.col].color << endl;\ }while(0) int main() { while(cin >> m >> n){ cin >> key; CLR(map_table); //clean table for(int row = 1; row <= m; row++) for(int col = 1; col <= n; col++) cin >> map_table[row][col].val; struct pos curr_pos, next_pos; curr_pos.row = 1; curr_pos.col = 1; find_key = false; GOTO_POS(curr_pos); while(!pos_store.empty()) { if(find_key){ break; /*break! we find ans*/ } curr_pos = pos_store.top(); LEFT_POS(curr_pos); //DBG_POS(curr_pos); int check_status = CHECK_VAL(curr_pos, key); switch(check_status){ case 0: find_key = true; break; case 1: next_pos = curr_pos; next_pos.row += 1; GOTO_POS(next_pos); next_pos = curr_pos; next_pos.col += 1; GOTO_POS(next_pos); break; case -1: next_pos = curr_pos; next_pos.row -= 1; GOTO_POS(next_pos); next_pos = curr_pos; next_pos.col -= 1; GOTO_POS(next_pos); break; default: cout << "error" << endl; exit(-1); } } cout << (find_key ? "Yes":"No") << endl; } return 0; } /************************************************************** Problem: 1384 User: xiyanxiyan10 Language: C++ Result: Time Limit Exceed ****************************************************************/
好吧,超时了
因而使用二分查找
#include <cstring> #include <iostream> #include <vector> #include <stack> #include <algorithm> #include <cstring> #include <stack> using namespace std; #define MAX_ROW 1100 #define MAX_COL 1100 int map_table[MAX_ROW][MAX_COL]; int tot_row, tot_col, key; int reverse_flag; bool find_key; #define CLR(a) memset(a, 0, sizeof(a)) /** * @brief vist the vertex * @param[in] i row num * @param[in] j col num * @note reverse_flag reverse the table * */ #define GET_VAL(i, j) (reverse_flag ? map_table[j][i] : map_table[i][j]) #define REVERSE_TABLE() do{\ tot_row = tot_row^tot_col;\ tot_col = tot_row^tot_col;\ tot_row = tot_row^tot_col;\ reverse_flag ^= 1;\ }while(0) #define INIT_TABLE() do{\ reverse_flag = 0;\ }while(0) int main() { while(cin >> tot_row >> tot_col){ cin >> key; INIT_TABLE(); for(int curr_row = 1; curr_row <= tot_row; curr_row++) for(int curr_col = 1; curr_col <= tot_col; curr_col++) cin >> map_table[curr_row][curr_col]; find_key = false; /*binary_search in row, so we make sure col > row*/ if(tot_col < (tot_row )){ REVERSE_TABLE(); } for(int curr_row = 1; (curr_row <= tot_row) && ( key > GET_VAL(curr_row, 1) ); curr_row++){ int left_col = 1; int right_col = tot_col; int curr_col; if(true == find_key){ break; } while(left_col <= right_col){ int val; curr_col = ((right_col - left_col) >> 1) + left_col; //cout << " row " << curr_row << " " << curr_col << endl; val = GET_VAL(curr_row, curr_col); if(key == val){ find_key = true; break; }else if(key > val){ left_col = curr_col + 1; }else{ right_col = curr_col - 1; } } } cout << (find_key ? "Yes":"No") << endl; } return 0; } /************************************************************** Problem: 1384 User: xiyanxiyan10 Language: C++ Result: Time Limit Exceed ****************************************************************/
依然超时,最终代码是
#include <cstring> #include <iostream> #include <vector> #include <stack> #include <algorithm> #include <cstring> #include <stack> #include <cstdio> using namespace std; #define MAX_ROW 1100 #define MAX_COL 1100 bool find_key; int tot_row, tot_col, key, tmp; int main() { int input_key; while(~scanf("%d%d%d", &tot_row, &tot_col, &key)){ find_key = false; for(int curr_row = 1; curr_row <= tot_row; curr_row++) for(int curr_col = 1; curr_col <= tot_col; curr_col++){ scanf("%d", &tmp); if(tmp == key){ find_key = true; } } printf(find_key ? "Yes\n":"No\n"); } return 0; }
代码的运行时数据来自内存仍是寄存器以及IO缓冲区可能对效率形成致命,须要关注。