#include <stdio.h> #include <vector> #include <iostream> #include <algorithm> #include <stdlib.h> using namespace std; typedef int ix; typedef int bilans; typedef pair<int, int> da; typedef pair<int, ix> d_ix; typedef pair<bilans, ix> bilans_ix; typedef pair<int, int> ipair; typedef pair<ipair, int> itriple; #define POP_HEAP(v) pop_heap((v).begin(),(v).end()); (v).pop_back(); #define PUSH_HEAP(v, e) v.push_back((e)); push_heap((v).begin(),(v).end()); vector<int> ds; vector<int> as; vector<int> kolejnosc; vector<d_ix> zatrudne; vector<bilans_ix> dozabicia; vector<itriple> pozostale; unsigned long long z; void return_NIE() { printf("NIE\n"); exit(0); } void return_TAK() { printf("TAK\n%i", kolejnosc[0]); for (int i=1; i<kolejnosc.size(); ++i) { printf(" %i", kolejnosc[i]); } printf("\n"); exit(0); } void zabij(int ix) { //printf("ZABIJAM ix=%i d=%i a=%i z=%i->%i\n", ix, ds[ix], as[ix], z, (z-ds[ix]+as[ix]) ); z = z-ds[ix]+as[ix]; kolejnosc.push_back(ix); } void printf_zatrunde() { for (vector<d_ix>::iterator i=zatrudne.begin(); i!=zatrudne.end(); ++i) { int ix = i->second; printf("zatrudne ix=%i d=%i a=%i\n", ix, ds[ix], as[ix]); } } int main() { int n,zz; scanf("%i%i", &n, &zz); z = zz; //Wczytanie ds.push_back(-1); as.push_back(-1); for (int ix=1; ix<=n; ++ix) { int d, a; scanf("%i%i", &d, &a); ds.push_back(d); as.push_back(a); if (d>=z) { zatrudne.push_back( d_ix(-d, ix) ); //na gorze najslabsze smoki } else { dozabicia.push_back( bilans_ix(a-d, ix) ); //na gorze smoki na ktorych sie najwiecej zyskuje/najmniej traci } } //Kopcowanie make_heap(zatrudne.begin(), zatrudne.end()); make_heap(dozabicia.begin(), dozabicia.end()); //Zabij te o nieujemnym bilansie while (dozabicia.size()>0) { int bilans = dozabicia.front().first; int ix = dozabicia.front().second; if (bilans<0) break; //jezeli najkorzystniejszy teraz do zabicia jest ujemny to przerwij zabij(ix); POP_HEAP(dozabicia); while (zatrudne.size()>0) { //tak dlugo jak sa jeszcze smoki int d = -zatrudne.front().first; int ix = zatrudne.front().second; int a = as[ix]; if (d>=z) break; //jezeli nie jest od nas silniejszy POP_HEAP(zatrudne); //przesun kolejnego ktorego mozna zabic PUSH_HEAP(dozabicia, bilans_ix(a-d, ix)); } } //Teraz jestesmy najsilniejsi //Oproznij wektor od zabicia: przenies do zatrudne while (dozabicia.size()>0) { int ix = dozabicia.front().second; POP_HEAP(dozabicia); zatrudne.push_back( d_ix(0, ix) ); } //Wszystko z zatrunde zrzuc do pozostale; for (int i=0; i<zatrudne.size(); ++i) { int ix = zatrudne[i].second; pozostale.push_back( itriple( ipair(as[ix], -ds[ix]), ix) ); } make_heap(pozostale.begin(), pozostale.end()); //Rozwalamy od najsilniejszego bo potem jestesmy coraz slabsi while (pozostale.size()>0) { int ix = pozostale.front().second; if (ds[ix]>=z) return_NIE(); //jezeli nie jest od nas silniejszy to go zabijamy zabij(ix); POP_HEAP(pozostale); } return_TAK(); 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 | #include <stdio.h> #include <vector> #include <iostream> #include <algorithm> #include <stdlib.h> using namespace std; typedef int ix; typedef int bilans; typedef pair<int, int> da; typedef pair<int, ix> d_ix; typedef pair<bilans, ix> bilans_ix; typedef pair<int, int> ipair; typedef pair<ipair, int> itriple; #define POP_HEAP(v) pop_heap((v).begin(),(v).end()); (v).pop_back(); #define PUSH_HEAP(v, e) v.push_back((e)); push_heap((v).begin(),(v).end()); vector<int> ds; vector<int> as; vector<int> kolejnosc; vector<d_ix> zatrudne; vector<bilans_ix> dozabicia; vector<itriple> pozostale; unsigned long long z; void return_NIE() { printf("NIE\n"); exit(0); } void return_TAK() { printf("TAK\n%i", kolejnosc[0]); for (int i=1; i<kolejnosc.size(); ++i) { printf(" %i", kolejnosc[i]); } printf("\n"); exit(0); } void zabij(int ix) { //printf("ZABIJAM ix=%i d=%i a=%i z=%i->%i\n", ix, ds[ix], as[ix], z, (z-ds[ix]+as[ix]) ); z = z-ds[ix]+as[ix]; kolejnosc.push_back(ix); } void printf_zatrunde() { for (vector<d_ix>::iterator i=zatrudne.begin(); i!=zatrudne.end(); ++i) { int ix = i->second; printf("zatrudne ix=%i d=%i a=%i\n", ix, ds[ix], as[ix]); } } int main() { int n,zz; scanf("%i%i", &n, &zz); z = zz; //Wczytanie ds.push_back(-1); as.push_back(-1); for (int ix=1; ix<=n; ++ix) { int d, a; scanf("%i%i", &d, &a); ds.push_back(d); as.push_back(a); if (d>=z) { zatrudne.push_back( d_ix(-d, ix) ); //na gorze najslabsze smoki } else { dozabicia.push_back( bilans_ix(a-d, ix) ); //na gorze smoki na ktorych sie najwiecej zyskuje/najmniej traci } } //Kopcowanie make_heap(zatrudne.begin(), zatrudne.end()); make_heap(dozabicia.begin(), dozabicia.end()); //Zabij te o nieujemnym bilansie while (dozabicia.size()>0) { int bilans = dozabicia.front().first; int ix = dozabicia.front().second; if (bilans<0) break; //jezeli najkorzystniejszy teraz do zabicia jest ujemny to przerwij zabij(ix); POP_HEAP(dozabicia); while (zatrudne.size()>0) { //tak dlugo jak sa jeszcze smoki int d = -zatrudne.front().first; int ix = zatrudne.front().second; int a = as[ix]; if (d>=z) break; //jezeli nie jest od nas silniejszy POP_HEAP(zatrudne); //przesun kolejnego ktorego mozna zabic PUSH_HEAP(dozabicia, bilans_ix(a-d, ix)); } } //Teraz jestesmy najsilniejsi //Oproznij wektor od zabicia: przenies do zatrudne while (dozabicia.size()>0) { int ix = dozabicia.front().second; POP_HEAP(dozabicia); zatrudne.push_back( d_ix(0, ix) ); } //Wszystko z zatrunde zrzuc do pozostale; for (int i=0; i<zatrudne.size(); ++i) { int ix = zatrudne[i].second; pozostale.push_back( itriple( ipair(as[ix], -ds[ix]), ix) ); } make_heap(pozostale.begin(), pozostale.end()); //Rozwalamy od najsilniejszego bo potem jestesmy coraz slabsi while (pozostale.size()>0) { int ix = pozostale.front().second; if (ds[ix]>=z) return_NIE(); //jezeli nie jest od nas silniejszy to go zabijamy zabij(ix); POP_HEAP(pozostale); } return_TAK(); return 0; } |