#define _CRT_SECURE_NO_WARNINGS #include #include #include #include #include #include #include #include #include typedef long long ll; using namespace std; const double TIME_LIMIT = 4.5; ll SQR(ll x) { return x*x; } string itos(int a) { string s; int pow10 = 1; while (a / (pow10) >= 10) pow10 *= 10; while (pow10) { s += '0' + ((a / pow10) % 10); pow10 /= 10; } return s; } struct bakery { long long int x; //x-coordinate long long int y; //y-coordinate }; struct party { long long int b; //begin long long int d; //duration long long int x; //x-coordinate long long int y; //y-coordinate }; struct partyTime { long long int b; //begin long long int d; //duration }; long long int n, k, p; long long int a[1 << 10][1 << 10]; long long int x, y; bakery bakeryData[1 << 20]; party partyData[1 << 20]; vector partyTable[1 << 10][1 << 10]; string output2; bool srt(party a, party b) { if (a.b> n >> p >> k; for (i = 1; i <= n; i++) { for (j = 1; j <= n; j++) { inputFile >> a[i][j]; partyTable[i][j].clear(); partyTable[i][j].push_back(tmp); if (a[i][j]>99 || a[i][j]<0) { return "ERROR! THE HEIGHT OF SOME CELL IN THE INPUT IS NOT BETWEEN 0 AND 100\n"; } } } inputFile >> x >> y; if (x<1 || x>n || y<1 || y>n) { return "ERROR! IVANCHO'S HOME IS PLACED OUTSIDE OF THE WORLD\n"; } for (i = 1; i <= p; i++) { inputFile >> partyData[i].x >> partyData[i].y >> partyData[i].b >> partyData[i].d; } sort(partyData + 1, partyData + p + 1, srt); for (i = 1; i <= p; i++) { tmp.b = partyData[i].b; tmp.d = partyData[i].d; partyTable[partyData[i].x][partyData[i].y].push_back(tmp); partyTable[partyData[i].x][partyData[i].y][0].b++; if (partyData[i].b<0) { return "ERROR! A PARTY BEGINS BEFORE THE BEGINING OF TIME\n"; } else { if (partyData[i].d<0) { return "ERROR! A PARTY LASTS NEGATIVE TIME\n"; } if (partyData[i].x<1 || partyData[i].x>n || partyData[i].y<1 || partyData[i].y>n) { cout << i << endl; cout << partyData[i].x << " " << partyData[i].y << endl; return "ERROR! A PARTY IS PLACED OUTSIDE OF THE WORLD\n"; } } } /*for(i=1;i<=p;i++) { cout<> bakeryData[i].x >> bakeryData[i].y; if (bakeryData[i].x<1 || bakeryData[i].y<1 || bakeryData[i].x>n || bakeryData[i].y>n) { return "ERROR! A BAKERY IS PLACED OUTSIDE OF THE TABLE\n"; } else { if (partyTable[bakeryData[i].x][bakeryData[i].y][0].b>0) { cout << i << endl << endl; return "ERROR! THERE IS PARTY IN BAKERY ZONE\n"; } else { if (bakeryData[i].x == x&&bakeryData[i].y == y) { return "ERROR! THERE IS BAKERY IN IVANCHO'S HOME\n"; } } } partyTable[bakeryData[i].x][bakeryData[i].y][0].b = -1; partyTable[bakeryData[i].x][bakeryData[i].y][0].d = -1; } } for (i = 1; i <= n; i++) { for (j = 1; j <= n; j++) { /*cout<<"_______\n"; cout<partyTable[i][j][ii + 1].b) { return "ERROR! PARTY BEGINS BEFORE THE PREVIOUS HAS ENDED\n"; } } } } if (partyTable[x][y][0].b>0) { return "ERROR! THERE IS PARTY IN IVANCHO'S HOME\n"; } else { return "INPUT OK\n"; } } string readOutput(string outputStr) { char c; size_t ln = outputStr.size(); output2 = ""; for (int i = 0; i= TIME_END) { return "WRONG ANSWER! IVANCHO'S TIMESHEET MUST BE OVER BEFORE THE 10 000 000 000 UNIT OF TIME\n"; } if (cx<1 || cy<1 || cx>n || cy>n) { return "WRONG ANSWER! IVANCHO CAN'T LEAVE THE WORLD\n"; } if (output[i] == 'R') { time += getDist(cx, cy, output[i], cakes); cy++; } else { if (output[i] == 'L') { time += getDist(cx, cy, output[i], cakes); cy--; } else { if (output[i] == 'D') { time += getDist(cx, cy, output[i], cakes); cx++; } else { if (output[i] == 'U') { time += getDist(cx, cy, output[i], cakes); cx--; } else { if (output[i] == '+') { if (partyTable[cx][cy][0].b == -1 && partyTable[cx][cy][0].d == -1) { return "WRONG ANSWER! IVANCHO IS TRYING TO ENTER A PARTY IN THE BAKERY\n"; } num = 0; while (output[i + 1] >= '0'&&output[i + 1] <= '9') { num *= 10; num += output[i + 1] - '0'; i++; if (num>cakes) { return "WRONG ANSWER! IVANCHO IS TRYING TO ENTER A PARTY WITH MORE CAKES THAN HE HAS\n"; } } while (partyTable[cx][cy][0].d <= partyTable[cx][cy][0].b) { if (time= partyTable[cx][cy][partyTable[cx][cy][0].d].b) { break; } else { if (time <= partyTable[cx][cy][partyTable[cx][cy][0].d].b) { break; } else { partyTable[cx][cy][0].d++; } } } if (partyTable[cx][cy][0].d>partyTable[cx][cy][0].b) { return "WRONG ANSWER! IVANCHO IS TRYING TO ENTER A PARTY IN A ZONE WHERE THERE ARE NO MORE PARTIES\n"; } if (time <= partyTable[cx][cy][partyTable[cx][cy][0].d].b + partyTable[cx][cy][partyTable[cx][cy][0].d].d) { ans += getHappines(partyTable[cx][cy][partyTable[cx][cy][0].d].b + partyTable[cx][cy][partyTable[cx][cy][0].d].d - max(time, partyTable[cx][cy][partyTable[cx][cy][0].d].b), num); cakes -= num; time = partyTable[cx][cy][partyTable[cx][cy][0].d].d + partyTable[cx][cy][partyTable[cx][cy][0].d].b; } } else { if (partyTable[cx][cy][0].b == -1 && partyTable[cx][cy][0].d == -1) { if (output[i] == '+') { return "WRONG ANSWER! IVANCHO IS TRYING TO ENTER A PARTY IN THE BAKERY\n"; } num = 0; long long int fl = 0; if (output[i]<'0' || output[i]>'9') { return "WRONG ANSWER! INVALID SYMBOL IN YOUR OUTPUT\n"; } while (output[i] >= '0'&&output[i] <= '9') { num *= 10; num += output[i] - '0'; i++; if (num >= 100000) { return "WRONG ANSWER! IVANCHO IS TRYING TO BUY MORE CAKES THAN HE IS ALLOWED TO\n"; } } i--; cakes += num; continue; } else { if (output[i] >= '0'&&output[i] <= '9') { return "WRONG ANSWER! IVANCHO IS TRYING TO BUY CAKES FROM A PLACE WHERE THERE IS NO BAKERY\n"; } else { return "WRONG ANSWER! INVALID SYMBOL IN YOUR OUTPUT\n"; } } } } } } } } return "OK " + itos(ans) + "\n"; } const long long maxTime = 100000 * 100000; ll findClosestAvailableParty(ll curx, ll cury, ll curTime, int curParty, int cakes) { if (curParty > p) return p; while (curParty <= p) { if (partyData[curParty].b + partyData[curParty].d < curTime) { curParty++; continue; } ll dist = myDist(curx, cury, partyData[curParty].x, partyData[curParty].y, cakes, DONOTAPPENDDIST); if (dist + curTime < maxTime && dist + curTime < partyData[curParty].b + partyData[curParty].d) { break; } curParty++; } return curParty; } pair findClosestCakeStore(ll cx, ll cy) { ll bx = 999999999, by = 999999999; for (int i = 1; i <= k; ++i) { if (abs(cx - bakeryData[i].x) + abs(cy - bakeryData[i].y) < abs(cx - bx) + abs(cy - by)) { bx = bakeryData[i].x; by = bakeryData[i].y; } } return make_pair(bx, by); } double startTime; string genTrivialSolution() { long long curTime = 0; ll curx = x, cury = y; string rez; ll curParty = 1; string tmp; int cakes = 0; while ((clock() / (double)CLOCKS_PER_SEC - startTime) < TIME_LIMIT && curTime < maxTime && curParty < p) { //if (n <= 100 || p <= 10000) { pair < ll, ll> closestCakeStore = findClosestCakeStore(curx, cury); curTime += myDist(curx, cury, closestCakeStore.first, closestCakeStore.second, 0, rez); curx = closestCakeStore.first; cury = closestCakeStore.second; //} // Buy some cakes // find closest available cake store // but cakes and then go to closest available party if (n <= 30 && p <= 1000) { cakes = 2500;// TODO } else { cakes = 2000; } ll bestParty = findClosestAvailableParty( curx, cury, curTime, curParty, cakes); ll bestCakes = cakes; /* int iters = 4; while (iters > 0) { cakes = iters * 1000; ll party = findClosestAvailableParty( curx, cury, curTime, curParty, cakes); if (party < bestParty) { bestCakes = cakes; } iters--; } */ curParty = bestParty; cakes = bestCakes; if (curParty > p) { break; } rez += itos(cakes); tmp = ""; curTime = partyData[curParty].b + partyData[curParty].d; myDist(curx, cury, partyData[curParty].x, partyData[curParty].y, cakes, rez); rez += '+'; if (cakes > 0) { rez += itos(cakes); } curx = partyData[curParty].x; cury = partyData[curParty].y; curParty++; cakes = 0; } // // to check the score // invoke output2 = res; // calculatePoints(res)! return rez; } int main() { startTime = clock() / (double)CLOCKS_PER_SEC; //freopen("party.in", "r", stdin); readInput("party.in"); freopen("party.out", "w", stdout); string trivialSolution = genTrivialSolution(); if (trivialSolution.size() == 0) { trivialSolution = y < n - 1 ? "R" : "L"; } //cerr << calculatePoints(trivialSolution) << endl; cout << trivialSolution << endl; return 0;