#include #include #include #include #include #include using namespace std; #define N 300001 int superOfficialPath[N], officialPath[N]; //, dp[N] /*array with current max len*/, cmi[N] /*array with current max index*/; int xaxis[N], yaxis[N], superXaxis[N], superYaxis[N]; int n, m, maxl, a[1000][1000], pot[4]; long long superScore = 0, currentScore; int counter, x, y, currentMax, currentMin, superCounter; bool mov[4]; double w[4], newDir, sum; clock_t TL = 2.95 * CLOCKS_PER_SEC; //int LIS_old(int start, int fin); int idx[N], val [N], len[N]; int LIS(int start, int fin) { int n = fin - start; idx[0] = 0; val[0] = officialPath[start]; len[0] = 1; for(int i = 1; i < n; ++i) { if(officialPath[start+i] < val[i-1]) { val[i] = officialPath[start+i]; idx[i] = i; } else { val[i] = val[i-1]; idx[i] = idx[i-1]; } len[i] = 1; } for(int i = 2; i <= n; ++i) { if(officialPath[start+i] > val[i]) { idx[i] = i; val[i] = officialPath[start+i]; ++len[i]; } for(int j = i; j < n; ++j) { if(idx[j] < j) { if(officialPath[start+j] > val[j]) { idx[j] = j; val[j] = officialPath[start+j]; ++len[j]; } } if(len[j] == len[j-1]) { if(val[j] > val[j-1]) { idx[j] = idx[j-1]; val[j] = val[j-1]; } else if(val[j] == val[j-1]) { if(idx[j] > idx[j-1]) { idx[j] = idx[j-1]; } } } else if(len[j] < len[j-1]) { idx[j] = idx[j-1]; val[j] = val[j-1]; len[j] = len[j-1]; } } } return len[n-1]; } int LDS(int start, int fin) { int n = fin - start; idx[0] = 0; val[0] = officialPath[start]; len[0] = 1; for(int i = 1; i < n; ++i) { if(officialPath[start+i] > val[i-1]) { val[i] = officialPath[start+i]; idx[i] = i; } else { val[i] = val[i-1]; idx[i] = idx[i-1]; } len[i] = 1; } for(int i = 2; i <= n; ++i) { if(officialPath[start+i] < val[i]) { idx[i] = i; val[i] = officialPath[start+i]; ++len[i]; } for(int j = i; j < n; ++j) { if(idx[j] < j) { if(officialPath[start+j] < val[j]) { idx[j] = j; val[j] = officialPath[start+j]; ++len[j]; } } if(len[j] == len[j-1]) { if(val[j] < val[j-1]) { idx[j] = idx[j-1]; val[j] = val[j-1]; } else if(val[j] == val[j-1]) { if(idx[j] > idx[j-1]) { idx[j] = idx[j-1]; } } } else if(len[j] < len[j-1]) { idx[j] = idx[j-1]; val[j] = val[j-1]; len[j] = len[j-1]; } } } return len[n-1]; } int main() { clock_t start_time = clock(); srand(42); ifstream inp; inp.open("path.in"); inp >> n >> m; for(int i = 0; i < n; i++) { for(int j = 0; j < m; ++j) { inp >> a[i][j]; } } inp >> maxl; inp.close(); while(clock() - start_time < TL) { counter = 0; x = rand() % n; y = rand() % m; while(a[x][y] == -1) { x = rand() % n; y = rand() % m; } xaxis[counter] = x; yaxis[counter] = y; officialPath[counter++] = a[x][y]; currentMax = officialPath[counter - 1]; currentMin = officialPath[counter - 1]; for(; counter < maxl; ++counter) { mov[0] = 0; mov[1] = 0; mov[2] = 0; mov[3] = 0; // move right if(y < n-1 && a[x][y+1] != -1) { mov[0] = 1; pot[0] = a[x][y+1]; } // move down if(x < m-1 && a[x+1][y] != -1) { mov[1] = 1; pot[1] = a[x+1][y]; } // move left if(y > 0 && a[x][y-1] != -1) { mov[2] = 1; pot[2] = a[x][y-1]; } // move up if(x > 0 && a[x-1][y] != -1) { mov[3] = 1; pot[3] = a[x-1][y]; } if(!(mov[0] || mov[1] || mov[2] || mov[3])) { break; } sum = 0; for(int i = 0; i < 4; ++i) { if(pot[i] > officialPath[0]) { if(pot[i] > currentMax) { w[i] = 0.1 + (pot[i] - currentMax)*2; } else { w[i] = 0.1 + currentMax - pot[i]; } } else { if(pot[i] < currentMin) { w[i] = 0.1 + (currentMin - pot[i])*2; } else { w[i] = 0.1 + pot[i] - currentMin; } } w[i] *= mov[i]; sum += w[i]; //cout << w[i] << " "; } //cout << "(" << sum << ") "; for(int i = 0; i < 4; ++i) { w[i] /= sum; //cout << w[i] << " "; } //cout << endl; newDir = (double)(rand() / RAND_MAX); if(newDir < w[0]) // move right { ++y; } else if(newDir < w[0] + w[1]) // move down { ++x; } else if(newDir < w[0] + w[1] + w[2]) // move left { --y; } else // move up { --x; } officialPath[counter] = a[x][y]; xaxis[counter] = x; yaxis[counter] = y; if(officialPath[counter] > currentMax) { currentMax = officialPath[counter]; } if(officialPath[counter] < currentMin) { currentMin = officialPath[counter]; } } // eval sol /* for(int i = 0; i < counter; ++i) { cout << "a[" << xaxis[i] << ", " << yaxis[i] << "]=" << officialPath[i] << endl; } */ currentScore = LIS(0, counter)*LDS(0, counter); //cout << "LIS = " << currentScore << endl; if(currentScore > superScore) { superScore = currentScore; memcpy(superOfficialPath, officialPath, counter*(sizeof(int))); memcpy(superXaxis, xaxis, counter*(sizeof(int))); memcpy(superYaxis, yaxis, counter*(sizeof(int))); superCounter = counter; } //break; } /* cout << superScore << endl; for(int i = 0; i < superCounter; ++i) { cout << "a[" << superXaxis[i] << ", " << superYaxis[i] << "]=" << superOfficialPath[i] << endl; } */ ofstream out; out.open("path.out"); out << superCounter << endl; for(int i = 0; i < superCounter; ++i) { out << superXaxis[i] + 1 << " " << superYaxis[i] + 1 << endl; } out.close(); //cout << clock() - start_time << endl; return 0; } /* int LIS_old(int start, int fin) { int n = fin-start; dp[0] = 1; cmi[0] = 0; for(int i = 1; i < n; ++i) { if(officialPath[start+i] > officialPath[start+cmi[i-1]]) { dp[i] = dp[i-1] + 1; cmi[i] = i; } else { dp[i] = dp[i-1]; cmi[i] = cmi[i-1]; } } cout <<"00\n"; for(int i = 0; i < n; ++i) { cout << dp[i] << " "; } cout << endl; for(int i = 0; i < n; ++i) { cout << cmi[i] << " "; } cout << endl; int max = dp[n-1]; for(int i = 1; i < n-1; ++i) { dp[i] = 1; cmi[i] = i; for(int j = i+1; j < n; ++j) { if(officialPath[start+j] > officialPath[start+cmi[j-1]]) { dp[j] = dp[j-1] + 1; cmi[j] = j; } else { dp[j] = dp[j-1]; cmi[j] = cmi[j-1]; } } cout << i << endl; for(int i = 0; i < n; ++i) { cout << dp[i] << " "; } cout << endl; for(int i = 0; i < n; ++i) { cout << cmi[i] << " "; } cout << endl; if(max < dp[n-1]) { max = dp[n-1]; } } return max; } */