/* problem: http://codeit.bg/bul/contest_files/download/50552 created: 13.01.2018 - fillArray(), printAnswer(), guessing; max memory: 1.53MiB, max runtime: 71ms, score: 0.110995304231169 to 2.59211162280109 14.01.2018 - points[][] + fillArray() update, findBestRow() (not used), guessing; max memory: 1.53MiB, max runtime: 82ms, score: 2.73756790142566 15.01.2018 - navigate(), findBestRow finds the optimal solution (sometimes incorrectly); max memory: 2.90Mib, max runtime: 176ms, score: 3.12610845799177 16.01.2018 - obstacles break, findBestRow finds the optimal solution correctly; max memory: 2.25MiB, max runtime: 194ms, score: 3.9437497371 17.01.2018 - specialModify(), higher scoring solution to A=C=0 case, it may not be optimal tho max memory: 2.26MiB, max runtime: 225ms, score: 3.965364163 18.01.2018 - returned to a earlier version (from 15.01.2018), unsuccessful recursion in navigate() 19.01.2018 - re-implemented several things and removed several things (incl. specialModify() func), new arrays (too many in fact), successful recursion in navigate() for adding edge obstacles max memory: 4.98MiB, max runtime: 704ms, score: 7.3966063827 re-write the program (style, clarity) + try recursion at every step */ //#include //DO NOT LEAVE IN THE FINAL SOLUTION only for tests #include //i/o files #include //fillArray() using namespace std; int N, M, A, C; //size of the given matrix, points for adding and changing obstacles const int n = 400, m = 400; char matrix[n][m]; bool broken[n][m]; bool newchanges[n][m]; char changed[n][m]; char finalm[n][m]; int points[n][m]; ifstream in("pinball.in"); ofstream out("pinball.out"); void fillArray() { //fills matrix and points using the input file int i = 0, j = 0; string s; in >> N >> M; in >> A >> C; for (i = 0; i < N; i++) { in >> s; for (j = 0; j < M; j++) { matrix[i][j] = s[j]; finalm[i][j] = matrix[i][j]; } } for (i = 0; i < N; i++) { for (j = 0; j < M; j++) { in >> points[i][j]; } } } void printArray(int row) { //writes the row and matrix (unchanged) in the output file out << row +1<< '\n'; int i = 0, j = 0; for (i = 0; i < N; i++) { for (j = 0; j < M; j++) { out << finalm[i][j]; } out << '\n'; } } void specialModify(){ int n=N, m=M; char ch; if(n%2==1)n--; if(m%2==1)m--; for(int i=0;i= N || column<0 || column >= M) { if(!broken[prevR][prevC] && prevR>=0 && prevC>=0){ int scH = score; changed[prevR][prevC] = '/'; newchanges[prevR][prevC] = true; int newScore1 = navigate(firstR); newScore1 -= A; changed[prevR][prevC] = '\\'; broken[prevR][prevC] = false; int newScore2 = navigate(firstR); newScore2 -= A; broken[prevR][prevC] = false; if (newScore1 > scH && newScore1 >= newScore2) { changed[prevR][prevC] = '/'; score = newScore1; } else if (newScore2 > scH && newScore2>newScore1) { changed[prevR][prevC] = '\\'; score = newScore2; } else changed[prevR][prevC] = '.'; newchanges[prevR][prevC] = false; } out = true; continue; } //obstacles & change in direction handling else { score += points[row][column]; if (changed[row][column] != '.' && (!broken[row][column] || tempnew[row][column])) { broken[row][column] = true; tempnew[row][column] = false; if (changed[row][column] == '/') { switch (direction) { case right: direction = up; break; case up: direction = right; break; case left: direction = down; break; case down: direction = left; break; } } if (changed[row][column] == '\\') { switch (direction) { case right: direction = down; break; case up: direction = left; break; case left: direction = up; break; case down: direction = right; break; } } } } } return score; } int findBestRow() { /*finds best row using navigate()*/ int i, score, bestRow = N, bestScore = 0; for (i = 0; i < N; i++) { for (int i = 0; i < N; i++) { for (int j = 0; j < M; j++) { changed[i][j] = matrix[i][j]; } } for (int i = 0; i < N; i++) { for (int j = 0; j < M; j++) { broken[i][j] = false; } } for (int i = 0; i < N; i++) { for (int j = 0; j < M; j++) { newchanges[i][j] = false; } } score = navigate(i); //out << "\n score, row: "<= bestScore) { for (int i = 0; i < N; i++) { for (int j = 0; j < M; j++) { finalm[i][j]=changed[i][j]; } } //out << " changed final "; bestRow = i; bestScore = score; } } return bestRow; } int main() { /*highest score so far using guessing int row = N; if (N > 2) row = N / 3;*/ fillArray(); in.close(); if(A==0&&C==0)specialModify(); int row = findBestRow(); printArray(row); out.close(); return 0; }