#include <cstdio> char seg[8008]; int zdalneL[8008],zdalneP[8008],biuroL[8008],biuroP[8008]; int n,spotkan,czas,ileBiuro,ileZdalne,biuro,zdalne,zajec,pominiete,czasNaZadanka,maxCzas=0; //1-spotkanie w biurze, 2-spotkanie zdalne, 3-czas wolny bool nieDaSie = true; bool debug = false; int main(){ scanf("%d %d %d",&n, &spotkan, &czas); scanf(" %s ",&seg); ileBiuro = 0; ileZdalne = 0; zdalneL[0] = zdalneP[n+1] = biuroL[0] = biuroP[n+1] = 0; //dp, sprawdz ile po lewej stronie podczas danego segmentu jest roznych czynnosci do wykonania //przyda sie do natychmiastowego wyliczenia for(int i=1; i<=n; i++){ if(seg[i-1] == '1'){ ++ileBiuro; } else if(seg[i-1] == '2'){ ++ileZdalne; } biuroL[i] = ileBiuro; zdalneL[i] = ileZdalne; } biuro = ileBiuro; zdalne = ileZdalne; biuroL[n+1] = biuroP[0] = biuro; zdalneL[n+1] = zdalneP[0] = zdalne; zajec = biuro + zdalne; ileBiuro = 0; ileZdalne = 0; //wykonaj zliczenia dla czynnosci po prawej stronie for(int i=n; i>0; i--){ if(seg[i-1] == '1'){ ++ileBiuro; } else if(seg[i-1] == '2'){ ++ileZdalne; } biuroP[i] = ileBiuro; zdalneP[i] = ileZdalne; } if(debug){ if(ileBiuro == biuro && ileZdalne == zdalne) printf("biuro:%d zdalnych:%d\n",biuro,zdalne); else printf("cos skopales!\n"); printf("na lewo...\n"); for(int i=0; i<=n+1; i++){ printf("%d ",biuroL[i]); } printf("\n"); for(int i=0; i<=n+1; i++){ printf("%d ",zdalneL[i]); } printf("\nna prawo...\n"); for(int i=0; i<=n+1; i++){ printf("%d ",biuroP[i]); } printf("\n"); for(int i=0; i<=n+1; i++){ printf("%d ",zdalneP[i]); } printf("\n"); } //sprawdz najpierw czy wogole oplaca ci sie wyjezdzac z domu :) if(biuro <= spotkan ){ int zajecia = biuro + zdalne; if(zajecia <= spotkan) printf("%d\n",n); else printf("%d\n",n-(zajecia-spotkan)); return 0; } //teraz przelec brute-forcem wszystkie mozliwe wyjazdy i powroty :) //a - wyjazd do pracy, b - powrot do domu for(int a = 1; a <= n-czas*2; a++) for(int b = a+czas+1; b <= n-czas+1; b++){ int a2 = a+czas-1; int b2 = b+czas-1; //printf("[%d %d] - [%d %d]\n",a,a2,b,b2); pominiete = 0; //odejmij pominiete spotkania podczas jazdy (zdalne lub w biurze) pominiete += zdalneL[a2] - zdalneL[a-1]; pominiete += biuroL[a2] - biuroL[a-1]; pominiete += zdalneP[b] - zdalneP[b2+1]; pominiete += biuroP[b] - biuroP[b2+1]; //odejmij takze wszystkie spotkania zaplanowane w pracy kiedy pracownik jest w domu if(a>1){ pominiete += biuroL[a-1] - biuroL[0]; } if(b2+1<=n){ pominiete += biuroP[b2+1] - biuroP[n+1]; } //jezeli ilosc koniecznie pominietych spotkan jest mniejsza lub rowna k oblicz czas na rozwiazanie zadan lub //przeznaczajac maksymalny czas na ich rozwiazanie, uwzgledniajac pominiecie kolejnych spotkan zdalnych if(pominiete <= spotkan){ nieDaSie = false; int pozostalyCzas = (a-1) + (n-b2); int pozostZdalne = 0; if(a>1){ pozostZdalne += zdalneL[a-1] - zdalneL[0]; } if(b2+1<=n){ pozostZdalne += zdalneP[b2+1] - zdalneP[n+1]; } int rest = spotkan - pominiete; czasNaZadanka = 0; if (pozostZdalne <= rest){ czasNaZadanka = pozostalyCzas; } else { czasNaZadanka = pozostalyCzas - pozostZdalne - rest; } if(czasNaZadanka>maxCzas) maxCzas = czasNaZadanka; } //printf("Pom: %d rest: %d,%d Zad: %d\n",pominiete,a-1,n-b2,czasNaZadanka); } if(nieDaSie) printf("-1\n"); else printf("%d\n",maxCzas); 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 | #include <cstdio> char seg[8008]; int zdalneL[8008],zdalneP[8008],biuroL[8008],biuroP[8008]; int n,spotkan,czas,ileBiuro,ileZdalne,biuro,zdalne,zajec,pominiete,czasNaZadanka,maxCzas=0; //1-spotkanie w biurze, 2-spotkanie zdalne, 3-czas wolny bool nieDaSie = true; bool debug = false; int main(){ scanf("%d %d %d",&n, &spotkan, &czas); scanf(" %s ",&seg); ileBiuro = 0; ileZdalne = 0; zdalneL[0] = zdalneP[n+1] = biuroL[0] = biuroP[n+1] = 0; //dp, sprawdz ile po lewej stronie podczas danego segmentu jest roznych czynnosci do wykonania //przyda sie do natychmiastowego wyliczenia for(int i=1; i<=n; i++){ if(seg[i-1] == '1'){ ++ileBiuro; } else if(seg[i-1] == '2'){ ++ileZdalne; } biuroL[i] = ileBiuro; zdalneL[i] = ileZdalne; } biuro = ileBiuro; zdalne = ileZdalne; biuroL[n+1] = biuroP[0] = biuro; zdalneL[n+1] = zdalneP[0] = zdalne; zajec = biuro + zdalne; ileBiuro = 0; ileZdalne = 0; //wykonaj zliczenia dla czynnosci po prawej stronie for(int i=n; i>0; i--){ if(seg[i-1] == '1'){ ++ileBiuro; } else if(seg[i-1] == '2'){ ++ileZdalne; } biuroP[i] = ileBiuro; zdalneP[i] = ileZdalne; } if(debug){ if(ileBiuro == biuro && ileZdalne == zdalne) printf("biuro:%d zdalnych:%d\n",biuro,zdalne); else printf("cos skopales!\n"); printf("na lewo...\n"); for(int i=0; i<=n+1; i++){ printf("%d ",biuroL[i]); } printf("\n"); for(int i=0; i<=n+1; i++){ printf("%d ",zdalneL[i]); } printf("\nna prawo...\n"); for(int i=0; i<=n+1; i++){ printf("%d ",biuroP[i]); } printf("\n"); for(int i=0; i<=n+1; i++){ printf("%d ",zdalneP[i]); } printf("\n"); } //sprawdz najpierw czy wogole oplaca ci sie wyjezdzac z domu :) if(biuro <= spotkan ){ int zajecia = biuro + zdalne; if(zajecia <= spotkan) printf("%d\n",n); else printf("%d\n",n-(zajecia-spotkan)); return 0; } //teraz przelec brute-forcem wszystkie mozliwe wyjazdy i powroty :) //a - wyjazd do pracy, b - powrot do domu for(int a = 1; a <= n-czas*2; a++) for(int b = a+czas+1; b <= n-czas+1; b++){ int a2 = a+czas-1; int b2 = b+czas-1; //printf("[%d %d] - [%d %d]\n",a,a2,b,b2); pominiete = 0; //odejmij pominiete spotkania podczas jazdy (zdalne lub w biurze) pominiete += zdalneL[a2] - zdalneL[a-1]; pominiete += biuroL[a2] - biuroL[a-1]; pominiete += zdalneP[b] - zdalneP[b2+1]; pominiete += biuroP[b] - biuroP[b2+1]; //odejmij takze wszystkie spotkania zaplanowane w pracy kiedy pracownik jest w domu if(a>1){ pominiete += biuroL[a-1] - biuroL[0]; } if(b2+1<=n){ pominiete += biuroP[b2+1] - biuroP[n+1]; } //jezeli ilosc koniecznie pominietych spotkan jest mniejsza lub rowna k oblicz czas na rozwiazanie zadan lub //przeznaczajac maksymalny czas na ich rozwiazanie, uwzgledniajac pominiecie kolejnych spotkan zdalnych if(pominiete <= spotkan){ nieDaSie = false; int pozostalyCzas = (a-1) + (n-b2); int pozostZdalne = 0; if(a>1){ pozostZdalne += zdalneL[a-1] - zdalneL[0]; } if(b2+1<=n){ pozostZdalne += zdalneP[b2+1] - zdalneP[n+1]; } int rest = spotkan - pominiete; czasNaZadanka = 0; if (pozostZdalne <= rest){ czasNaZadanka = pozostalyCzas; } else { czasNaZadanka = pozostalyCzas - pozostZdalne - rest; } if(czasNaZadanka>maxCzas) maxCzas = czasNaZadanka; } //printf("Pom: %d rest: %d,%d Zad: %d\n",pominiete,a-1,n-b2,czasNaZadanka); } if(nieDaSie) printf("-1\n"); else printf("%d\n",maxCzas); return 0; } |