#include <iostream> #include <algorithm> #include <vector> #include <cstdlib> using namespace std; typedef long long int ll; ll odl(vector<ll> &x, int y){ ll suma = 0; for(vector<ll>::iterator it=x.begin(); it!=x.end(); it++){ suma += abs(*it - y); } return suma; } pair<ll, ll> przeciecie(pair<ll, ll> z1, pair<ll, ll> z2){ if(z1.first > z1.second || z2.first > z2.second){ cout << "zle " << z1.first << ' ' <<z1.second << ' ' << z2.first << ' ' << z2.second << endl; } pair<ll, ll> ret; if(z2.first > z1.second || z2.second < z1.first){ ret.first = 20000000000000; ret.second = 20000000000000; } else{ ret.first = max(z1.first, z2.first); ret.second = min(z1.second, z2.second); } return ret; } void rek(pair<ll, ll> zakres, vector<ll> &x, int d, int k, ll s, int y_cnt, vector<pair<int, ll> > &wyniki){ if(d == k){ int y1, y2; if(y_cnt == 0){ y1 = zakres.first; y2 = (zakres.first + zakres.second) / 2; } else{ pair<ll, ll> z; if(y_cnt < 0){ z.first = -1000000000000; z.second = s / y_cnt; } else{ z.first = (s / y_cnt) * -1; z.second = 1000000000000; } z = przeciecie(z, zakres); y1 = z.first; y2 = z.second; } if(y1 != 20000000000000){ pair<int, ll> wynik; wynik.first = y1; wynik.second = odl(x, y1); wyniki.push_back(wynik); wynik.first = y1-1; wynik.second = odl(x, y1-1); wyniki.push_back(wynik); wynik.first = y1+1; wynik.second = odl(x, y1+1); wyniki.push_back(wynik); } if(y2 != 20000000000000){ pair<int, ll> wynik; wynik.first = y2; wynik.second = odl(x, y2); wyniki.push_back(wynik); wynik.first = y2-1; wynik.second = odl(x, y2-1); wyniki.push_back(wynik); wynik.first = y2+1; wynik.second = odl(x, y2+1); wyniki.push_back(wynik); } } else{ pair<ll, ll> zakres1, zakres2; zakres1.first = -1000000000000; zakres1.second = x[d]; zakres2.first = x[d]; zakres2.second = 1000000000000; zakres1 = przeciecie(zakres, zakres1); zakres2 = przeciecie(zakres, zakres2); if(zakres1.first != 20000000000000) rek(zakres1, x, d+1, k, s + x[d], y_cnt -1, wyniki); if(zakres2.first != 20000000000000) rek(zakres2, x, d+1, k, s - x[d], y_cnt + 1, wyniki); } } bool comp(const pair<int, ll> &p1, const pair<int, ll> &p2){ return p1.second < p2.second; } int main(){ ios_base::sync_with_stdio(0); int n, k; cin >> n >> k; //k=2; vector<vector <ll> > ciagi; for(int i=0; i<k; i++){ vector<ll> ciag; ciag.assign(n, 0); for(int j=0; j<n; j++){ cin >> ciag[j]; } ciagi.push_back(ciag); } vector<int> wynik; if(k==2){ //bool czy=false; ll s1, s2; s1 = s2 = 0; for(int i=0; i<n; i++){ int w; w = (ciagi[0][i] + ciagi[1][i]) / 2; s1 += abs(ciagi[0][i] - w); s2 += abs(ciagi[1][i] - w); if(s1 > s2){ if(ciagi[0][i] < w) w--; else w++; s1--; s2++; } else if(s2 > s1){ if(ciagi[0][i] < w) w++; else w--; s1++; s2--; } wynik.push_back(w); } } else{ for(int i=0; i<n; i++){ vector<ll> x; ll x_min, x_max; x_min = 2000000000000; x_max = -2000000000000; for(int j=0; j<k; j++){ x.push_back(ciagi[j][i]); x_min = min(x_min, ciagi[j][i]); x_max = max(x_max, ciagi[j][i]); } pair<ll, ll> zakres, zakres1, zakres2; zakres.first = x_min; zakres.second = x_max; if(x_min == x_max) cout << x_min << ' '; else{ int y = 0; vector<pair<int, ll> > wyniki; zakres1.first = x_min; zakres1.second = x[0]; zakres2.first = x[0]; zakres2.second = x_max; rek(zakres1, x, 1, k, x[0], -1, wyniki); rek(zakres2, x, 1, k, -x[0], 1, wyniki); sort(wyniki.begin(), wyniki.end(), comp); y = wyniki[0].first; //cout << y << ' ' << wyniki.size() << "; "; //cout << y << ' '; wynik.push_back(y); } } //cout << s; //cout << endl; } ll max_s = -1; for(int i=0; i<k; i++){ ll s=0; for(int j=0; j<n; j++){ s += abs(wynik[j] - ciagi[i][j]); max_s = max(max_s, s); } } //cout << max_s << endl; for(int i=0; i<n; i++){ cout << wynik[i] << ' '; } cout << endl; return 0; }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 | #include <iostream> #include <algorithm> #include <vector> #include <cstdlib> using namespace std; typedef long long int ll; ll odl(vector<ll> &x, int y){ ll suma = 0; for(vector<ll>::iterator it=x.begin(); it!=x.end(); it++){ suma += abs(*it - y); } return suma; } pair<ll, ll> przeciecie(pair<ll, ll> z1, pair<ll, ll> z2){ if(z1.first > z1.second || z2.first > z2.second){ cout << "zle " << z1.first << ' ' <<z1.second << ' ' << z2.first << ' ' << z2.second << endl; } pair<ll, ll> ret; if(z2.first > z1.second || z2.second < z1.first){ ret.first = 20000000000000; ret.second = 20000000000000; } else{ ret.first = max(z1.first, z2.first); ret.second = min(z1.second, z2.second); } return ret; } void rek(pair<ll, ll> zakres, vector<ll> &x, int d, int k, ll s, int y_cnt, vector<pair<int, ll> > &wyniki){ if(d == k){ int y1, y2; if(y_cnt == 0){ y1 = zakres.first; y2 = (zakres.first + zakres.second) / 2; } else{ pair<ll, ll> z; if(y_cnt < 0){ z.first = -1000000000000; z.second = s / y_cnt; } else{ z.first = (s / y_cnt) * -1; z.second = 1000000000000; } z = przeciecie(z, zakres); y1 = z.first; y2 = z.second; } if(y1 != 20000000000000){ pair<int, ll> wynik; wynik.first = y1; wynik.second = odl(x, y1); wyniki.push_back(wynik); wynik.first = y1-1; wynik.second = odl(x, y1-1); wyniki.push_back(wynik); wynik.first = y1+1; wynik.second = odl(x, y1+1); wyniki.push_back(wynik); } if(y2 != 20000000000000){ pair<int, ll> wynik; wynik.first = y2; wynik.second = odl(x, y2); wyniki.push_back(wynik); wynik.first = y2-1; wynik.second = odl(x, y2-1); wyniki.push_back(wynik); wynik.first = y2+1; wynik.second = odl(x, y2+1); wyniki.push_back(wynik); } } else{ pair<ll, ll> zakres1, zakres2; zakres1.first = -1000000000000; zakres1.second = x[d]; zakres2.first = x[d]; zakres2.second = 1000000000000; zakres1 = przeciecie(zakres, zakres1); zakres2 = przeciecie(zakres, zakres2); if(zakres1.first != 20000000000000) rek(zakres1, x, d+1, k, s + x[d], y_cnt -1, wyniki); if(zakres2.first != 20000000000000) rek(zakres2, x, d+1, k, s - x[d], y_cnt + 1, wyniki); } } bool comp(const pair<int, ll> &p1, const pair<int, ll> &p2){ return p1.second < p2.second; } int main(){ ios_base::sync_with_stdio(0); int n, k; cin >> n >> k; //k=2; vector<vector <ll> > ciagi; for(int i=0; i<k; i++){ vector<ll> ciag; ciag.assign(n, 0); for(int j=0; j<n; j++){ cin >> ciag[j]; } ciagi.push_back(ciag); } vector<int> wynik; if(k==2){ //bool czy=false; ll s1, s2; s1 = s2 = 0; for(int i=0; i<n; i++){ int w; w = (ciagi[0][i] + ciagi[1][i]) / 2; s1 += abs(ciagi[0][i] - w); s2 += abs(ciagi[1][i] - w); if(s1 > s2){ if(ciagi[0][i] < w) w--; else w++; s1--; s2++; } else if(s2 > s1){ if(ciagi[0][i] < w) w++; else w--; s1++; s2--; } wynik.push_back(w); } } else{ for(int i=0; i<n; i++){ vector<ll> x; ll x_min, x_max; x_min = 2000000000000; x_max = -2000000000000; for(int j=0; j<k; j++){ x.push_back(ciagi[j][i]); x_min = min(x_min, ciagi[j][i]); x_max = max(x_max, ciagi[j][i]); } pair<ll, ll> zakres, zakres1, zakres2; zakres.first = x_min; zakres.second = x_max; if(x_min == x_max) cout << x_min << ' '; else{ int y = 0; vector<pair<int, ll> > wyniki; zakres1.first = x_min; zakres1.second = x[0]; zakres2.first = x[0]; zakres2.second = x_max; rek(zakres1, x, 1, k, x[0], -1, wyniki); rek(zakres2, x, 1, k, -x[0], 1, wyniki); sort(wyniki.begin(), wyniki.end(), comp); y = wyniki[0].first; //cout << y << ' ' << wyniki.size() << "; "; //cout << y << ' '; wynik.push_back(y); } } //cout << s; //cout << endl; } ll max_s = -1; for(int i=0; i<k; i++){ ll s=0; for(int j=0; j<n; j++){ s += abs(wynik[j] - ciagi[i][j]); max_s = max(max_s, s); } } //cout << max_s << endl; for(int i=0; i<n; i++){ cout << wynik[i] << ' '; } cout << endl; return 0; } |