Submission #349719

#TimeUsernameProblemLanguageResultExecution timeMemory
349719MatijaLCarnival Tickets (IOI20_tickets)C++14
27 / 100
1067 ms186328 KiB
/** * Author: MatijaL * Time: 2021-01-17 18:15:39 **/ #include <tickets.h> #include <bits/stdc++.h> using namespace std; typedef long long ll; #define pll pair<ll, ll> #define loop(i, n) for(ll i = 0; i < n; i++) #define FOR(i,n,m) for(ll i = n; i <= m; i++) #define isIn(vec, item) find(vec.begin(), vec.end(), item) != vec.end() #define fs first #define sc second #define pb push_back #define mp make_pair #define all(v) v.begin(),v.end() #define inf 1000000005 #define mod 1000000007 #define print(v) for(auto e : v) cout << e << " "; cout << endl; #define limit 1600 ll median; struct Card{ int color, pos; ll num; ll worth; Card(int a, int b, ll c){ color = a; pos = b; num = c; worth = abs(num - median); } bool operator < (const Card& other){ if(worth!=other.worth) return worth > other.worth; return pos < other.pos; } }; ll find_maximum(int K, vector<vector<int>> x){ int n = x.size(); int m = x[0].size(); vector<Card> cards[n]; vector<ll> allNumbers; vector<vector<int>> out(n, vector<int>(m, -1)); loop(i, n)loop(j, m) allNumbers.pb(x[i][j]); sort(all(allNumbers)); int mid = (m*n)/2 -1; median = allNumbers[mid]; loop(i, n)loop(j, m) cards[i].pb(Card(i, j, x[i][j])); //printf("MEDIAN is %lld\n", median); loop(i, n) sort(all(cards[i])); vector<Card> left[n]; vector<Card> right[n]; vector<int> pointL(n, 0); vector<int> pointR(n, 0); //pair<cost, color> right -> subLeft vector<pll> subLeft; vector<pll> subRight; //1. k najboljsih vsake barve loop(color, n){ int cnt = 0; int pl = -1; int pr = -1; for(auto e : cards[color]){ //printf("Card %d %d %lld\n", e.color, e.pos, e.worth); if(cnt < K){ cnt++; if(e.num <= median) left[color].pb(e); else right[color].pb(e); pl = left[color].size()-1; pr = right[color].size()-1; pointL[color] = pl; pointR[color] = pr; }else{ if(e.num <= median){ left[color].pb(e); //probaj dat iz desne if(pr >= 0) subLeft.pb(mp(right[color][pr].worth - e.worth, color)); pr--; }else{ right[color].pb(e); //daj z leve if(pl >= 0) subRight.pb(mp(left[color][pl].worth - e.worth, color)); pl--; } } if(pointL[color] > inf) pointL[color] = -1; if(pointR[color] > inf) pointR[color] = -1; } } /* //printf("Pre-BALANCING\n"); loop(color, n){ //printf("Left: "); loop(i, pointL[color]+1) //printf("%lld ", left[color][i].num); //printf("\n"); //printf("Right: "); loop(i, pointR[color]+1) //printf("%lld ", right[color][i].num); //printf("\n"); }*/ //2. uravnovesi /* loop(color, n) //printf("%d %d\n", pointL[color], pointR[color]); //printf("SUBSTITUTIONS:\n"); //printf("Left: "); for(auto e : subLeft) //printf("(%lld %lld) ", e.fs, e.sc); //printf("\n"); //printf("Right: "); for(auto e : subRight) //printf("(%lld %lld) ", e.fs, e.sc); //printf("\n"); */ int leftCnt = 0; int rightCnt = 0; loop(i, n) leftCnt += pointL[i]+1; loop(i, n) rightCnt += pointR[i]+1; //printf("left cnt %d | right cnt %d\n", leftCnt, rightCnt); sort(all(subLeft)); sort(all(subRight)); for(auto e : subLeft){ if(leftCnt >= rightCnt) break; //printf("one to the left\n"); int curColor = e.sc; leftCnt++; rightCnt--; pointL[curColor]++; pointR[curColor]--; } for(auto e : subRight){ if(rightCnt >= leftCnt) break; //printf("one to the right\n"); int curColor = e.sc; rightCnt++; leftCnt--; pointR[curColor]++; pointL[curColor]--; } /* //printf("BALANCING\n"); loop(color, n){ //printf("Left: "); loop(i, pointL[color]+1) //printf("%lld ", left[color][i].num); //printf("\n"); //printf("Right: "); loop(i, pointR[color]+1) //printf("%lld ", right[color][i].num); //printf("\n"); }*/ ll ans = 0; //3 lotimo se dela momci loop(k, K){ //printf("k = %lld assembly: ", k); int cl = 0; int cr = 0; set<int> usedColors; //nastimaj leve loop(color, n){ if(usedColors.count(color) or pointL[color] < 0) continue; if(cl == n/2) break; Card c = left[color][pointL[color]]; pointL[color]--; out[c.color][c.pos] = k; cl++; ans += c.worth; usedColors.insert(color); //printf("%lld ", c.num); } //pa se desne loop(color, n){ if(usedColors.count(color) or pointR[color] < 0) continue; if(cr == n/2) break; Card c = right[color][pointR[color]]; pointR[color]--; out[c.color][c.pos] = k; cr++; ans += c.worth; usedColors.insert(color); //printf("%lld ", c.num); } //printf("\n"); //assert(cl == n/2 and cr == n/2); } allocate_tickets(out); return ans; }
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...