From 471f6ea66a79efbc644566b4aaacedc804608051 Mon Sep 17 00:00:00 2001 From: kbokis Date: Wed, 19 Mar 2025 21:32:34 +0200 Subject: [PATCH 1/5] 37b-cauldron-and-shroompath solutions --- _data/contests/37-PDP.yml | 16 +- .../source_code/code/37-PDP/cauldron/TASK | 41 ++ .../code/37-PDP/cauldron/cauldron_brute.cc | 36 ++ .../37-PDP/cauldron/cauldron_brute_recurse.cc | 34 ++ .../code/37-PDP/cauldron/cauldron_correct.cc | 31 ++ .../code/37-PDP/cauldron/cauldron_subtask2.cc | 13 + .../code/37-PDP/cauldron/cauldron_subtask3.cc | 24 + .../source_code/code/37-PDP/shroompath/TASK | 53 +++ .../code/37-PDP/shroompath/shroom_brute1.cc | 47 ++ .../code/37-PDP/shroompath/shroom_brute2.cc | 40 ++ .../code/37-PDP/shroompath/shroom_only_a.cc | 27 ++ .../code/37-PDP/shroompath/shroom_only_b.cc | 27 ++ .../37-PDP/shroompath/shroom_solution1.cc | 30 ++ .../37-PDP/shroompath/shroom_solution2.cc | 43 ++ .../shroompath/shroom_solution3_math.cc | 42 ++ assets/37-b-shroompath-a.svg | 343 ++++++++++++++ assets/37-b-shroompath-b.svg | 339 ++++++++++++++ assets/37-b-shroompath-exp1.svg | 326 +++++++++++++ assets/37-b-shroompath-full.svg | 439 ++++++++++++++++++ contests/_36-PDP/c-bureaucracy-solution.md | 12 +- contests/_37-PDP/b-cauldron-solution.md | 65 +++ contests/_37-PDP/b-shroompath-solution.md | 160 +++++++ 22 files changed, 2174 insertions(+), 14 deletions(-) create mode 100755 _includes/source_code/code/37-PDP/cauldron/TASK create mode 100755 _includes/source_code/code/37-PDP/cauldron/cauldron_brute.cc create mode 100755 _includes/source_code/code/37-PDP/cauldron/cauldron_brute_recurse.cc create mode 100755 _includes/source_code/code/37-PDP/cauldron/cauldron_correct.cc create mode 100755 _includes/source_code/code/37-PDP/cauldron/cauldron_subtask2.cc create mode 100755 _includes/source_code/code/37-PDP/cauldron/cauldron_subtask3.cc create mode 100755 _includes/source_code/code/37-PDP/shroompath/TASK create mode 100755 _includes/source_code/code/37-PDP/shroompath/shroom_brute1.cc create mode 100755 _includes/source_code/code/37-PDP/shroompath/shroom_brute2.cc create mode 100755 _includes/source_code/code/37-PDP/shroompath/shroom_only_a.cc create mode 100755 _includes/source_code/code/37-PDP/shroompath/shroom_only_b.cc create mode 100755 _includes/source_code/code/37-PDP/shroompath/shroom_solution1.cc create mode 100755 _includes/source_code/code/37-PDP/shroompath/shroom_solution2.cc create mode 100755 _includes/source_code/code/37-PDP/shroompath/shroom_solution3_math.cc create mode 100755 assets/37-b-shroompath-a.svg create mode 100755 assets/37-b-shroompath-b.svg create mode 100755 assets/37-b-shroompath-exp1.svg create mode 100755 assets/37-b-shroompath-full.svg create mode 100755 contests/_37-PDP/b-cauldron-solution.md create mode 100755 contests/_37-PDP/b-shroompath-solution.md diff --git a/_data/contests/37-PDP.yml b/_data/contests/37-PDP.yml index 2a066586..9c66b99e 100644 --- a/_data/contests/37-PDP.yml +++ b/_data/contests/37-PDP.yml @@ -52,10 +52,10 @@ cauldron: statement_pdf_url: "https://drive.google.com/file/d/1tFvY_3m4KCz4ldE3vyLLsidE-PYt1hQs/view" statement_md: true testcases_url: "" - solution: false - solution_author: "" - codes_in_git: false - solution_tags: [] + solution: true + solution_author: "Κωνσταντίνος Μποκής" + codes_in_git: true + solution_tags: [sorting, greedy] on_judge: false shroompath: @@ -64,10 +64,10 @@ shroompath: statement_pdf_url: "https://drive.google.com/file/d/1tFvY_3m4KCz4ldE3vyLLsidE-PYt1hQs/view" statement_md: true testcases_url: "" - solution: false - solution_author: "" - codes_in_git: false - solution_tags: [] + solution: true + solution_author: "Κωνσταντίνος Μποκής" + codes_in_git: true + solution_tags: [greedy, modulo, binary counting] on_judge: false mergegame: diff --git a/_includes/source_code/code/37-PDP/cauldron/TASK b/_includes/source_code/code/37-PDP/cauldron/TASK new file mode 100755 index 00000000..b9a5c5ce --- /dev/null +++ b/_includes/source_code/code/37-PDP/cauldron/TASK @@ -0,0 +1,41 @@ +TASK( + name = "cauldron", + test_count = 33, + files_dir = "testdata/37-PDP/cauldron/", + input_file = "cauldron.in", + output_file = "cauldron.out", + time_limit = 1, + mem_limit = 64, + solutions = [ + SOLUTION( + name = "cauldron_brute", + source = "cauldron_brute.cc", + passes_up_to = 9, + lang = "c++", + ), + SOLUTION( + name = "cauldron_brute_recurse", + source = "cauldron_brute_recurse.cc", + passes_up_to = 9, + lang = "c++", + ), + SOLUTION( + name = "cauldron_subtask2", + source = "cauldron_subtask2.cc", + passes_only = [3,8,10,11,12,13,14,15,17,19,23,27,31], + lang = "c++", + ), + SOLUTION( + name = "cauldron_subtask3", + source = "cauldron_subtask3.cc", + passes_only = [3,8,10,11,12,13,14,15,16,17,18,19,20,21,23,27,31], + lang = "c++", + ), + SOLUTION( + name = "cauldron_correct", + source = "cauldron_correct.cc", + passes_all, + lang = "c++", + ), + ] +) diff --git a/_includes/source_code/code/37-PDP/cauldron/cauldron_brute.cc b/_includes/source_code/code/37-PDP/cauldron/cauldron_brute.cc new file mode 100755 index 00000000..deea3fcb --- /dev/null +++ b/_includes/source_code/code/37-PDP/cauldron/cauldron_brute.cc @@ -0,0 +1,36 @@ +#include +#include +#include + +using namespace std; + +typedef long long ll; + +int main(){ +#ifdef CONTEST + freopen("cauldron.in","r",stdin); + freopen("cauldron.out","w",stdout); +#endif + long t, N, K, c; + scanf("%ld%ld%ld%ld",&t,&N,&K,&c); + vector w(N); + ll ans = 0; + for(auto& x:w) + scanf("%ld",&x); + if(N<=20){ + for(long s=0,m=(1L<=w[i]){ + test += w[i] + c; + Krem -= w[i]; + } + } + test += Krem; + ans = max(ans,test); + } + } + printf("%lld\n",ans); + return 0; +} diff --git a/_includes/source_code/code/37-PDP/cauldron/cauldron_brute_recurse.cc b/_includes/source_code/code/37-PDP/cauldron/cauldron_brute_recurse.cc new file mode 100755 index 00000000..b362adbd --- /dev/null +++ b/_includes/source_code/code/37-PDP/cauldron/cauldron_brute_recurse.cc @@ -0,0 +1,34 @@ +#include +#include +using namespace std; + +typedef long long ll; + +long t, N, K, c; +long w[20]; +ll ans; + +void calc(long Krem,int i,ll csum=0){//Krem=μαγικό νερο στο καζάνι, csum=κέρδος από τα c + if(i==N){ + ans = max(ans, K + csum); + return; + } + calc(Krem,i+1,csum);//αν δεν πάρουμε το i + if(Krem>=w[i])//έχουμε αρκετό μαγικό νερό; + calc(Krem-w[i],i+1,csum+c);//αν πάρουμε το i +} + +int main(){ +#ifdef CONTEST + freopen("cauldron.in","r",stdin); + freopen("cauldron.out","w",stdout); +#endif + scanf("%ld%ld%ld%ld",&t,&N,&K,&c); + if(t==1){ + for(int i=0;i +#include +#include +using namespace std; + +typedef long long ll; + +int main(){ +#ifdef CONTEST + freopen("cauldron.in","r",stdin); + freopen("cauldron.out","w",stdout); +#endif + long t, N, K, c; + scanf("%ld%ld%ld%ld",&t,&N,&K,&c); + vector w(N); + ll ans = K; + for(auto& x:w) + scanf("%ld",&x); + if(c>0){ + sort(w.begin(),w.end()); + long Krem = K;//πόσο μαγικό νερό παραμένει στο καζάνι + for(auto e:w){ + if(e<=Krem){ + ans += c; + Krem -= e; + } else break; + } + } + printf("%lld\n",ans); + return 0; +} diff --git a/_includes/source_code/code/37-PDP/cauldron/cauldron_subtask2.cc b/_includes/source_code/code/37-PDP/cauldron/cauldron_subtask2.cc new file mode 100755 index 00000000..d8fd2502 --- /dev/null +++ b/_includes/source_code/code/37-PDP/cauldron/cauldron_subtask2.cc @@ -0,0 +1,13 @@ +#include +using namespace std; + +int main(){ +#ifdef CONTEST + freopen("cauldron.in","r",stdin); + freopen("cauldron.out","w",stdout); +#endif + long t, N, K, c; + scanf("%ld%ld%ld%ld",&t,&N,&K,&c); + printf("%ld\n",K); + return 0; +} diff --git a/_includes/source_code/code/37-PDP/cauldron/cauldron_subtask3.cc b/_includes/source_code/code/37-PDP/cauldron/cauldron_subtask3.cc new file mode 100755 index 00000000..2f79a2f5 --- /dev/null +++ b/_includes/source_code/code/37-PDP/cauldron/cauldron_subtask3.cc @@ -0,0 +1,24 @@ +#include +#include +using namespace std; + +typedef long long ll; + +int main(){ +#ifdef CONTEST + freopen("cauldron.in","r",stdin); + freopen("cauldron.out","w",stdout); +#endif + long t, N, K, c, w0; + scanf("%ld%ld%ld%ld",&t,&N,&K,&c); + ll ans = K; + if(t==3){ + scanf("%ld",&w0);//διάβασε ποσότητα ζωμού ενός βάζου + if(c>0){ + long jars = min(K/w0,N); + ans += (ll)jars*c; + } + } + printf("%lld\n",ans); + return 0; +} diff --git a/_includes/source_code/code/37-PDP/shroompath/TASK b/_includes/source_code/code/37-PDP/shroompath/TASK new file mode 100755 index 00000000..7dbac26b --- /dev/null +++ b/_includes/source_code/code/37-PDP/shroompath/TASK @@ -0,0 +1,53 @@ +TASK( + name = "shroompath", + test_count = 37, + files_dir = "testdata/37-PDP/shroompath/", + input_file = "shroompath.in", + output_file = "shroompath.out", + time_limit = 1, + mem_limit = 64, + solutions = [ + SOLUTION( + name = "shroom_brute_recursion", + source = "shroom_brute1.cc", + passes_up_to = 10, + lang = "c++", + ), + SOLUTION( + name = "shroom_brute_loop", + source = "shroom_brute2.cc", + passes_up_to = 10, + lang = "c++", + ), + SOLUTION( + name = "shroom_only_a", + source = "shroom_only_a.cc", + passes_only = [1,3,5,8,9,11,12,13,14,15,16,17,25,29,30,31,35,36,37], + lang = "c++", + ), + SOLUTION( + name = "shroom_only_b", + source = "shroom_only_b.cc", + passes_only = [2,4,6,7,10,18,19,20,21,22,23,24,26,27,28,32,33,34], + lang = "c++", + ), + SOLUTION( + name = "shroom_solution1", + source = "shroom_solution1.cc", + passes_all, + lang = "c++", + ), + SOLUTION( + name = "shroom_solution2", + source = "shroom_solution2.cc", + passes_all, + lang = "c++", + ), + SOLUTION( + name = "shroom_solution3", + source = "shroom_solution3_math.cc", + passes_all, + lang = "c++", + ), + ] +) diff --git a/_includes/source_code/code/37-PDP/shroompath/shroom_brute1.cc b/_includes/source_code/code/37-PDP/shroompath/shroom_brute1.cc new file mode 100755 index 00000000..dc6579db --- /dev/null +++ b/_includes/source_code/code/37-PDP/shroompath/shroom_brute1.cc @@ -0,0 +1,47 @@ +#include +#include +#include + +using namespace std; +int t,S,X,Y; +long ans = 1000000013; +vector Z; + +const char shrooms[] = "ab";//επιτρεπτοί χαρακτήρες +void add_length_w(vector& str,int pos){ + //υπολόγισε όλους τους συνδυασμούς ξεκινώντας από τη θέση pos + if(pos == str.size()){//καλύφθηκε το επιθυμητό μήκος + Z.insert(Z.end(),str.begin(),str.end()); + return; + } + for(int i=0;shrooms[i]!=0;i++){ + str[pos] = shrooms[i]; + add_length_w(str,pos+1); + } +} + +int main(){ +#ifdef CONTEST + freopen("shroompath.in","r",stdin); + freopen("shroompath.out","w",stdout); +#endif + scanf("%d%d%d%d",&t,&S,&X,&Y); + int A = (X>0) ? (S+X-1)/X : -1; + int B = (Y>0) ? (S+Y-1)/Y : -1; + for(int w=1;w<=max(A,B);w++){ + vector str(w); + add_length_w(str,0); + } + if(A>0){ + vector f(A,'a'); + long pos = search(Z.begin(), Z.end(), f.begin(), f.end()) - Z.begin(); + ans = min(ans,pos+A); + } + if(B>0){ + vector f(B,'b'); + long pos = search(Z.begin(), Z.end(), f.begin(), f.end()) - Z.begin(); + ans = min(ans,pos+B); + } + printf("%ld\n",ans); + return 0; +} diff --git a/_includes/source_code/code/37-PDP/shroompath/shroom_brute2.cc b/_includes/source_code/code/37-PDP/shroompath/shroom_brute2.cc new file mode 100755 index 00000000..aca0fce4 --- /dev/null +++ b/_includes/source_code/code/37-PDP/shroompath/shroom_brute2.cc @@ -0,0 +1,40 @@ +#include +#include +#include + +using namespace std; +int t,S,X,Y; +long ans = 1000000000; +vector Z; + +void add_length_w(int w){ + for(int i=0;i < (1<=0;j--) + Z.push_back((i & (1<0) ? (S+X-1)/X : -1; + int B = (Y>0) ? (S+Y-1)/Y : -1; + for(int w=1;w<=max(A,B);w++) + add_length_w(w); + + if(X>0){ + vector f(A,'a'); + long pos = search(Z.begin(), Z.end(), f.begin(), f.end()) - Z.begin(); + ans = min(ans,pos+A); + } + if(Y>0){ + vector f(B,'b'); + long pos = search(Z.begin(), Z.end(), f.begin(), f.end()) - Z.begin(); + ans = min(ans,pos+B); + } + + printf("%ld\n",ans); + return 0; +} diff --git a/_includes/source_code/code/37-PDP/shroompath/shroom_only_a.cc b/_includes/source_code/code/37-PDP/shroompath/shroom_only_a.cc new file mode 100755 index 00000000..5c2250c2 --- /dev/null +++ b/_includes/source_code/code/37-PDP/shroompath/shroom_only_a.cc @@ -0,0 +1,27 @@ +#include +using namespace std; + +typedef long long ll; +const ll mod = 1000000007; +long t,S,X,Y; + +long calc_a(int A){ + ll pow2 = 1;//2^0 + ll prev=0;//άθροισμα μανιταριών που προσπεράσαμε στα προηγούμενα μήκη + for(long i=1;;i++){ + pow2 = (pow2 * 2) % mod;//2^i + if(A<=2*i-1) return (prev + A) % mod; + prev = (prev + pow2*i) % mod; + } + return -1L; +} + +int main(){ +#ifdef CONTEST + freopen("shroompath.in","r",stdin); + freopen("shroompath.out","w",stdout); +#endif + scanf("%ld%ld%ld%ld",&t,&S,&X,&Y); + if(X>0)printf("%ld\n",calc_a((S+X-1)/X)); + return 0; +} diff --git a/_includes/source_code/code/37-PDP/shroompath/shroom_only_b.cc b/_includes/source_code/code/37-PDP/shroompath/shroom_only_b.cc new file mode 100755 index 00000000..6468acaf --- /dev/null +++ b/_includes/source_code/code/37-PDP/shroompath/shroom_only_b.cc @@ -0,0 +1,27 @@ +#include +using namespace std; + +typedef long long ll; +const ll mod = 1000000007; +long t,S,X,Y; + +long calc_b(int B){ + ll pow2 = 1;//2^0 + ll prev=0;//άθροισμα μανιταριών που προσπεράσαμε στα προηγούμενα μήκη + for(long i=1;;i++){ + if(i==B) return (prev + pow2*i + 1) % mod; + pow2 = (pow2 * 2) % mod;//2^i + prev = (prev + pow2*i) % mod; + } + return -1L; +} + +int main(){ +#ifdef CONTEST + freopen("shroompath.in","r",stdin); + freopen("shroompath.out","w",stdout); +#endif + scanf("%ld%ld%ld%ld",&t,&S,&X,&Y); + if(Y>0)printf("%ld\n",calc_b((S+Y-1)/Y)); + return 0; +} diff --git a/_includes/source_code/code/37-PDP/shroompath/shroom_solution1.cc b/_includes/source_code/code/37-PDP/shroompath/shroom_solution1.cc new file mode 100755 index 00000000..8f890306 --- /dev/null +++ b/_includes/source_code/code/37-PDP/shroompath/shroom_solution1.cc @@ -0,0 +1,30 @@ +#include +using namespace std; + +typedef long long ll; +const ll mod = 1000000007; +long t,S,X,Y,A,B; + +long calc(int A, int B){ + ll pow2 = 1; + ll prev=0;//σύνολο μανιταριων που προσπερασαμε + for(int i=1;;i++){//για όλα τα πλάτη απο 1 έως ... + if(A<=2*i-1) return (prev + A) % mod; + if(i == B) return (prev + pow2*i + 1) % mod; + pow2 = (pow2 * 2) % mod; + prev = (prev + pow2*i) % mod; + } + return -1L; +} + +int main(){ +#ifdef CONTEST + freopen("shroompath.in","r",stdin); + freopen("shroompath.out","w",stdout); +#endif + scanf("%ld%ld%ld%ld",&t,&S,&X,&Y); + A = (X>0) ? (S+X-1)/X : mod; + B = (Y>0) ? (S+Y-1)/Y : mod; + printf("%ld\n",calc(A,B)); + return 0; +} diff --git a/_includes/source_code/code/37-PDP/shroompath/shroom_solution2.cc b/_includes/source_code/code/37-PDP/shroompath/shroom_solution2.cc new file mode 100755 index 00000000..427a7154 --- /dev/null +++ b/_includes/source_code/code/37-PDP/shroompath/shroom_solution2.cc @@ -0,0 +1,43 @@ +#include +using namespace std; + +typedef long long ll; +const ll mod = 1000000007; +long t,S,X,Y,A,B; + +long calc_a(long A){ + ll pow2 = 1, prev = 0; + for(long i=1;2*i-1=A) + return calc_a(A); + else + return calc_b(B); +} + +int main(){ +#ifdef CONTEST + freopen("shroompath.in","r",stdin); + freopen("shroompath.out","w",stdout); +#endif + scanf("%ld%ld%ld%ld",&t,&S,&X,&Y); + printf("%ld\n",calc(S,X,Y)); + return 0; +} diff --git a/_includes/source_code/code/37-PDP/shroompath/shroom_solution3_math.cc b/_includes/source_code/code/37-PDP/shroompath/shroom_solution3_math.cc new file mode 100755 index 00000000..d72e246d --- /dev/null +++ b/_includes/source_code/code/37-PDP/shroompath/shroom_solution3_math.cc @@ -0,0 +1,42 @@ +#include +using namespace std; + +typedef long long ll; +const ll mod = 1000000007; +long t,S,X,Y,A,B; + +ll pow2(long a){ + if(a == 0)return 1; + ll z = pow2(a/2); + z = (z * z) % mod; + if(a&1) + z = (z * 2) % mod; + return z; +} + +ll f(long w){ return (pow2(w)*w)%mod; } + +ll p(long w){ return (pow2(w+1)*(w-1)+2) % mod; } + +long calc(int s,int x,int y){ + long A = x ? ((s+x-1)/x) : mod; + long B = y ? ((s+y-1)/y) : mod; + if(B*2-1>=A){ + return (p(A/2) + A)%mod; + }else{ + ll w = f(B); + //το w πρέπει να είναι άρτιος ώστε να μπορεί να διαιρεθεί με το 2 + if(w & 1)w+=mod;//μετατροπή του w σε ισοδύναμο άρτιο (ως προς mod) + return (p(B-1) + w/2+1)%mod; + } +} + +int main(){ +#ifdef CONTEST + freopen("shroompath.in","r",stdin); + freopen("shroompath.out","w",stdout); +#endif + scanf("%ld%ld%ld%ld",&t,&S,&X,&Y); + printf("%ld\n",calc(S,X,Y)); + return 0; +} diff --git a/assets/37-b-shroompath-a.svg b/assets/37-b-shroompath-a.svg new file mode 100755 index 00000000..f6cc766b --- /dev/null +++ b/assets/37-b-shroompath-a.svg @@ -0,0 +1,343 @@ + + + + + pdp37-b2-1 + + + + + + image/svg+xml + + pdp37-b2-1 + + + + + + + α + + + β + + + αα + + ββ + + βα + + αβ + + + ααα + + ααβ + + αβα + + αββ + + βαα + + βαβ + + ββα + + βββ + + + diff --git a/assets/37-b-shroompath-b.svg b/assets/37-b-shroompath-b.svg new file mode 100755 index 00000000..b60b8352 --- /dev/null +++ b/assets/37-b-shroompath-b.svg @@ -0,0 +1,339 @@ + + + + + pdp37-b2-1 + + + + + + image/svg+xml + + pdp37-b2-1 + + + + + + + α + + + β + + + αα + + ββ + + βα + + αβ + + + ααα + + ααβ + + αβα + + αββ + + βαα + + βαβ + + ββα + + βββ + + + diff --git a/assets/37-b-shroompath-exp1.svg b/assets/37-b-shroompath-exp1.svg new file mode 100755 index 00000000..3fb1a0fa --- /dev/null +++ b/assets/37-b-shroompath-exp1.svg @@ -0,0 +1,326 @@ + + + + + pdp37-b2-1 + + + + + + image/svg+xml + + pdp37-b2-1 + + + + + + + + α + + β + + + + αα + + ββ + + βα + + αβ + + + + ααα + + ααβ + + αβα + + αββ + + βαα + + βαβ + + ββα + + βββ + + + + diff --git a/assets/37-b-shroompath-full.svg b/assets/37-b-shroompath-full.svg new file mode 100755 index 00000000..676d8dcf --- /dev/null +++ b/assets/37-b-shroompath-full.svg @@ -0,0 +1,439 @@ + + + + + pdp37-b2-1 + + + + + + image/svg+xml + + pdp37-b2-1 + + + + + + + + + + + + α + + + + + β + + + + + + + + + + + + αα + + + + ββ + + + + βα + + + + αβ + + + + + + + + + + + + ααα + + + ααβ + + + αβα + + + + αββ + + + + βαα + + + + + βαβ + + + + ββα + + + + βββ + + + + + + + + diff --git a/contests/_36-PDP/c-bureaucracy-solution.md b/contests/_36-PDP/c-bureaucracy-solution.md index 31739d59..6855f160 100755 --- a/contests/_36-PDP/c-bureaucracy-solution.md +++ b/contests/_36-PDP/c-bureaucracy-solution.md @@ -30,8 +30,8 @@ codename: bureaucracy [^1]: Η αφαίρεση των διπλότυπων δεν είναι απαραίτητη για τη λύση του προβλήματος αλλά ενδέχεται να μειώνει τα βήματα της δυαδικής αναζήτησης καθώς δεν θα ελέγξουμε πάνω από μια φορά καμία τιμή $$L_{limit}$$. ```c++ - std::sort(W.begin(), W.end()); - W.erase(std::unique(W.begin(), W.end()), W.end()); + std::sort(W.begin(), W.end()); + W.erase(std::unique(W.begin(), W.end()), W.end()); ``` **Μειώνοντας τον αριθμό των αρχικών κόμβων:** Αντί να δοκιμάσουμε αναζήτηση κατά πλάτος για ένα $$L_{limit}$$ από κάθε αρχικό κόμβο και να πρέπει να ενώσουμε τα αποτελέσματα των αναζητήσεων στο τέλος για να δούμε αν καταφέραμε να φτάσουμε σε όλους τους τελικούς κόμβους, μπορούμε @@ -41,10 +41,10 @@ codename: bureaucracy ![Παράδειγμα εκφώνησης με dummy κόμβο](/assets/36-c-bureaucracy-sample1dummy.svg){:width="320px"} ```c++ - for(long i=0,s; i +Παράδειγμα για μήκη 1,2,3 + + +Για κάθε γράμμα **α** ή **β** έχουμε ένα συγκεκριμένο βάρος ($$X$$ και $$Y$$ αντίστοιχα). Zητείται πότε θα έχουμε +συγκεντρώσει συνολικό βάρος μεγέθους τουλάχιστον $$S$$ ως άθροισμα συνεχόμενων *ίδιων* γραμμάτων **α** ή **β**. + +**Παρατήρηση 1:** εφόσον θέλουμε το βάρος $$S$$ να αποτελείται αποκλειστικά από ίδια γράμματα +(έστω $$A$$ γράμματα **α** ή $$B$$ γράμματα **β**), αρκεί να διαιρέσουμε το +βάρος $$S$$ με το βάρος $$X$$ ή $$Y$$ *στρογγυλοποιώντας προς τα πάνω*, για να υπολογίσουμε τα $$A$$ και $$B$$. +Στα μαθηματικά ο συμβολισμός για τη στρογγυλοποίηση προς τα πάνω είναι +$$A = \lceil S/X \rceil, B = \lceil S/Y \rceil$$. +H συνάρτηση ``ceil`` της βιβλιοθήκης ``cmath`` κάνει ακριβώς αυτή τη στρογγυλοποίηση. +Εναλλακτικά, στη ``c++`` γνωρίζουμε ότι η ακέραια διαίρεση αγνοεί τυχόν δεκαδικά ψηφία, οπότε για το $$A$$ +αρκεί να κάνουμε τον υπολογισμό $$ A = (S+X-1)/X$$ (δηλαδή αυξάνουμε τόσο το $$S$$, +ώστε να αυξήσει το πηλίκο αν και μόνο αν η διαίρεση +του $$S$$ με το $$X$$ δεν είναι τέλεια). + +## Υποπρόβλημα 1 ($$ S\le 15 $$) + +Στο υποπρόβλημα αυτό θα χρειαστεί να εξερευνήσουμε τις συμβολοσειρές με μήκος $$1,2,\dots ,S$$, καθώς ο +πρώτος συνδυασμός συμβολοσειρών μήκους $$S$$ αποτελείται από $$S$$ **α** και ο τελευταίος από $$S$$ **β**. +Μάλιστα αν τα $$X$$ και $$Y$$ είναι μεγαλύτερα από $$1$$, θα καταφέρουμε να συγκεντρώσουμε +βάρος $$S$$ ακόμα πιο γρήγορα. +Ακολουθούν δύο τρόποι για να υπολογίσουμε όλους τους συνδυασμούς, με αναδρομή και με βρόγχο. + +**Αναδρομικά:** Βρίσκουμε όλους τους συνδυασμούς για κάθε μήκος συμβολοσειράς και τους προσθέσουμε σε έναν πίνακα +χαρακτήρων ``Z``. + +{% include code.md solution_name='shroom_brute1.cc' start=10 end=21 %} + +Κατόπιν με τη χρήση της συνάρτησης ``search`` της βιβλιοθήκης ``algorithm`` βρίσκουμε την +πρώτη θέση που ξεκινούν τα $$A$$ συνεχόμενα **α** ή τα $$B$$ συνεχόμενα **β** που αναζητούμε. + +{% include code.md solution_name='shroom_brute1.cc' start=35 end=44 %} + +**Παρατήρηση 2:** Το πλήθος των συμβολοσειρών μήκους $$i$$ από τα δύο γράμματα, είναι $$2^i$$ (εφόσον κάθε θέση μπορεί να έχει +$$2$$ τιμές). Τα **α** και **β** μπορούν να θεωρηθούν ως οι αριθμοί $$0$$ και $$1$$ του δυαδικού συστήματος και η +παραγόμενη συμβολοσειρά να είναι η αλληλουχία όλων των μη μηδενικών φυσικών αριθμών απεικονισμένων στο δυαδικό σύστημα. + +**Με βρόγχο:** Γνωρίζοντας από την *παρατήρηση 2* το πλήθος των συμβολοσειρών, τις κατασκευάζουμε με βρόγχο. + +{% include code.md solution_name='shroom_brute2.cc' start=10 end=14 %} + +Η λύση χρειάζεται $$\mathcal{O}(S\cdot 2^S)$$ χρόνο. +Μπορείτε να βρείτε ολόκληρο τον κώδικα των δύο παραπάνω λύσεων +[εδώ (αναδρομικά)]({% include link_to_source.md solution_name='shroom_brute1.cc' %}) και +[εδώ (με βρόγχο)]({% include link_to_source.md solution_name='shroom_brute2.cc' %}). + +## Υποπρόβλημα 2 ($$ Χ\gt Y $$) + +Εφόσον οι χαρακτήρες τύπου **α** έχουν μεγαλύτερο βάρος, θα προλάβουμε να συγκεντρώσουμε το συνολικό βάρος $$S$$ με αυτά. +Τα μανιτάρια **β** δεν θα μας χρησιμεύσουν. + +**Παρατήρηση 3:** Για οποιοδήποτε μήκος $$w$$ συμβολοσειρών με $$w\gt 1$$, η πρώτη συμβολοσειρά αποτελείται από $$w$$ **α** και +η επόμενη από $$w-1$$ **α** και ένα **β**. Σε καμία άλλη θέση δεν έχουμε τόσα **α** συγκεντρωμένα. + +
+Μεγάλος συνδυασμός α +
+ +Γνωρίζοντας το πλήθος των συμβολοσειρών για κάποιο μήκος (*παρατήρηση 2*) και τη θέση που +βρίσκονται τα περισσότερα συγκεντρωμένα **α** (*παρατήρηση 3*), δεν χρειάζεται να κατασκευάσουμε +τις συμβολοσειρές παρά μόνο να υπολογίσουμε πόσοι χαρακτήρες υπήρξαν σε όλα τα προηγούμενα μήκη συνδυασμών +και σε ποιά θέση συγκεντρώσαμε τα απαραίτητα **α**. + +{% include code.md solution_name='shroom_only_a.cc' start=8 end=17 %} +Ο χρόνος που χρειάζεται αυτή η λύση είναι $$\mathcal{O}(S)$$. +Ολόκληρος ο κώδικας [εδώ]({% include link_to_source.md solution_name='shroom_only_a.cc' %}). + +## Υποπρόβλημα 3 ($$ Χ=0 $$) + +Στο υποπρόβλημα αυτό, τα **α** έχουν μηδενικό βάρος και δεν χρησιμεύουν. Παρατηρώντας την παρακάτω εικόνα είναι +φανερό ότι η μέγιστη συγκέντρωση από **β** βρίσκεται στο μέσο σχεδόν των συμβολοσειρών μήκους $$B$$. Πιο +συγκεκριμένα, οι πρώτες μισές συμβολοσειρές έχουν **α** στην πρώτη θέση και οι επόμενες μισές έχουν **β** στην πρώτη θέση. +Η τελευταία συμβολοσειρά με **α** πρώτο χαρακτήρα, έχει $$B-1$$ χαρακτήρες **β** να ακολουθούν και αμέσως +μετά ακολουθεί η πρώτη συμβολοσειρά με ένα **β** στην πρώτη θέση. Αυτή είναι και η θέση που καταφέρνουμε +να συγκεντρώσουμε τα $$B$$ **β**, δηλαδή μια θέση μετά τους μισούς χαρακτήρες των συνδυασμών μήκους $$B$$. + +
+Μεγάλος συνδυασμός β +
+ +{% include code.md solution_name='shroom_only_b.cc' start=8 end=18 %} +Ο χρόνος που χρειάζεται η λύση αυτή είναι $$\mathcal{O}(S)$$. +Ολόκληρος ο κώδικας [εδώ]({% include link_to_source.md solution_name='shroom_only_b.cc' %}). + +## Πλήρης λύση σε χρόνο $$\mathcal{O}(S)$$ + +Εφόσον γνωρίζουμε τις συγκεντρώσεις $$A$$ ή $$B$$ που χρειαζόμαστε για βάρος $$S$$, πρέπει να βρούμε μετά από πόσους +χαρακτήρες θα τις καταφέρουμε. Οι χαρακτήρες **α** και **β** όμως είναι τόσα πολλοί που +ξεπερνούν τα όρια των ακεραίων τύπων που παρέχει η ``c++`` και δεν μπορούμε να αποθηκεύσουμε +τις θέσεις που τα βρήκαμε παρά μόνο αν αποθηκεύσουμε τα υπόλοιπα των θέσεων με +κάποιον διαιρέτη όπως το $$10^9+7$$ που μας δίνει η εκφώνηση. +Η διάταξη των θέσεων έχει χαθεί από τη στιγμή που κρατάμε μόνο τα υπόλοιπα τους, +οπότε υπολογίζουμε προοδευτικά τους συνδυασμούς +**α** και **β** που συναντάμε και σταματάμε μόλις βρούμε την πρώτη λύση. + +{% include code.md solution_name='shroom_solution1.cc' start=8 end=18 %} +Ολόκληρος ο κώδικας [εδώ]({% include link_to_source.md solution_name='shroom_solution1.cc' %}). + +Αν όμως αξιοποιήσουμε την πληροφορία ότι τα $$B$$ μανιτάρια τύπου **β** τα συναντάμε στις συμβολοσειρές μήκους $$B$$, είναι +φανερό ότι μέχρι και $$2\cdot B-1$$ μανιτάρια τύπου **α** τα βρίσκουμε νωρίτερα από τα $$B$$ **β**. + +
+Όλοι οι συνδυασμοί +
+ +Ενώνοντας τις λύσεις των δύο προηγούμενων υποπροβλημάτων, έχουμε: + +{% include code.md solution_name='shroom_solution2.cc' start=26 end=33 %} +Ολόκληρος ο κώδικας [εδώ]({% include link_to_source.md solution_name='shroom_solution2.cc' %}). +Οι παραπάνω λύσεις χρειάζονται χρόνο $$\mathcal{O}(S)$$. + +## Πλήρης λύση σε χρόνο $$\mathcal{O}(\log_2{S})$$ + +Ο αριθμός των χαρακτήρων από όλους τους συνδυασμούς ενός μόνο πλάτους $$k$$, +δίνεται από τη συνάρτηση +$$f(k) = 2^k \cdot k$$. Ο υπολογισμός του συνόλου των μανιταριών μέχρι και το πλάτος $$k$$, δίνεται από +τη συνάρτηση $$p(k) = f(1)+f(2)+\dots+f(k)=\sum_{i=1}^{k}f(i) = \sum_{i=1}^{k} {i\cdot 2^i}$$.
+Η συνάρτηση αυτή μπορεί να υπολογισθεί με +$$p(k) = 2^{k+1}\cdot (k-1)+2$$ + +*Απόδειξη:*
+Θα χρησιμοποιήσουμε επαγωγή.
+Για $$k=1$$, έχουμε $$p(1) = 2^{1+1}\cdot {1-1} +2 = 2$$ το οποίο ισχύει (έχουμε $$2$$ χαρακτήρες, ένα **α** και ένα **β** στους συνδυασμούς με μήκος $$1$$).
+Έστω ότι ισχύει για κάποιο $$k$$, δηλαδή $$p(k) = 2^{k+1}\cdot (k-1)+2$$,
+θα αποδείξουμε ότι ισχύει και για το $$k+1$$, δηλαδή:
+$$p(k+1)=2^{(k+1)+1}\cdot ((k+1)-1)+2 =2^{k+2}\cdot k + 2$$.
+ +Γνωρίζουμε ότι
+$$\begin{aligned} +p(k+1) =\\ +p(k) + f(k+1) =\\ +2^{k+1}\cdot (k-1)+2 + 2^{k+1} \cdot (k+1)=\\ +2^{k+1}\cdot k - 2^{k+1} + 2 + 2^{k+1}\cdot k + 2^{k+1}=\\ +2^{k+1}\cdot k - \cancel{2^{k+1}} + 2 + 2^{k+1}\cdot k + \cancel{2^{k+1}}=\\ +2^{k+1}\cdot k + 2^{k+1}\cdot k + 2=\\ +2\cdot 2^{k+1} \cdot k + 2=\\ +2^{k+2}\cdot k +2 +\end{aligned}$$
+άρα καταλήγουμε ότι ισχύει η $$p(k+1)$$, άρα η σχέση μας ισχύει για όλα τα $$k\ge1$$. + +Ο υπολογισμός της δύναμης με τη συνάρτηση ``pow2`` στην παραπάνω λύση, χρειάζεται +λογαριθμικό χρόνο ως προς τον εκθέτη (μέγιστος εκθέτης ο $$S$$), +οπότε ο χρόνος που χρειάζεται συνολικά η λύση είναι $$\mathcal{O}(\log_2{S})$$. +Ο σχετικός κώδικας ακολουθεί: +{% include code.md solution_name='shroom_solution3_math.cc' start=17 end=32 %} +Ολόκληρος ο κώδικας [εδώ]({% include link_to_source.md solution_name='shroom_solution3_math.cc' %}) From 4bb5ddf51b43d90f328f8267ed6a503f0d02e5c1 Mon Sep 17 00:00:00 2001 From: kbokis Date: Thu, 20 Mar 2025 10:44:40 +0200 Subject: [PATCH 2/5] updates to comments, improvements --- .../code/37-PDP/cauldron/cauldron_brute.cc | 1 - .../code/37-PDP/cauldron/cauldron_subtask2.cc | 1 - .../code/37-PDP/shroompath/shroom_brute1.cc | 2 +- .../code/37-PDP/shroompath/shroom_brute2.cc | 2 +- .../code/37-PDP/shroompath/shroom_only_a.cc | 1 - .../code/37-PDP/shroompath/shroom_only_b.cc | 1 - .../37-PDP/shroompath/shroom_solution1.cc | 1 - .../37-PDP/shroompath/shroom_solution2.cc | 1 - .../shroompath/shroom_solution3_math.cc | 3 +- contests/_37-PDP/b-cauldron-solution.md | 21 ++++--- contests/_37-PDP/b-shroompath-solution.md | 60 ++++++++++--------- 11 files changed, 47 insertions(+), 47 deletions(-) diff --git a/_includes/source_code/code/37-PDP/cauldron/cauldron_brute.cc b/_includes/source_code/code/37-PDP/cauldron/cauldron_brute.cc index deea3fcb..c5ceaf4e 100755 --- a/_includes/source_code/code/37-PDP/cauldron/cauldron_brute.cc +++ b/_includes/source_code/code/37-PDP/cauldron/cauldron_brute.cc @@ -1,7 +1,6 @@ #include #include #include - using namespace std; typedef long long ll; diff --git a/_includes/source_code/code/37-PDP/cauldron/cauldron_subtask2.cc b/_includes/source_code/code/37-PDP/cauldron/cauldron_subtask2.cc index d8fd2502..91ea5a09 100755 --- a/_includes/source_code/code/37-PDP/cauldron/cauldron_subtask2.cc +++ b/_includes/source_code/code/37-PDP/cauldron/cauldron_subtask2.cc @@ -1,5 +1,4 @@ #include -using namespace std; int main(){ #ifdef CONTEST diff --git a/_includes/source_code/code/37-PDP/shroompath/shroom_brute1.cc b/_includes/source_code/code/37-PDP/shroompath/shroom_brute1.cc index dc6579db..196b8cf8 100755 --- a/_includes/source_code/code/37-PDP/shroompath/shroom_brute1.cc +++ b/_includes/source_code/code/37-PDP/shroompath/shroom_brute1.cc @@ -1,8 +1,8 @@ #include #include #include - using namespace std; + int t,S,X,Y; long ans = 1000000013; vector Z; diff --git a/_includes/source_code/code/37-PDP/shroompath/shroom_brute2.cc b/_includes/source_code/code/37-PDP/shroompath/shroom_brute2.cc index aca0fce4..3a7e2ae9 100755 --- a/_includes/source_code/code/37-PDP/shroompath/shroom_brute2.cc +++ b/_includes/source_code/code/37-PDP/shroompath/shroom_brute2.cc @@ -1,8 +1,8 @@ #include #include #include - using namespace std; + int t,S,X,Y; long ans = 1000000000; vector Z; diff --git a/_includes/source_code/code/37-PDP/shroompath/shroom_only_a.cc b/_includes/source_code/code/37-PDP/shroompath/shroom_only_a.cc index 5c2250c2..1f886b57 100755 --- a/_includes/source_code/code/37-PDP/shroompath/shroom_only_a.cc +++ b/_includes/source_code/code/37-PDP/shroompath/shroom_only_a.cc @@ -1,5 +1,4 @@ #include -using namespace std; typedef long long ll; const ll mod = 1000000007; diff --git a/_includes/source_code/code/37-PDP/shroompath/shroom_only_b.cc b/_includes/source_code/code/37-PDP/shroompath/shroom_only_b.cc index 6468acaf..22b5216d 100755 --- a/_includes/source_code/code/37-PDP/shroompath/shroom_only_b.cc +++ b/_includes/source_code/code/37-PDP/shroompath/shroom_only_b.cc @@ -1,5 +1,4 @@ #include -using namespace std; typedef long long ll; const ll mod = 1000000007; diff --git a/_includes/source_code/code/37-PDP/shroompath/shroom_solution1.cc b/_includes/source_code/code/37-PDP/shroompath/shroom_solution1.cc index 8f890306..07d1c184 100755 --- a/_includes/source_code/code/37-PDP/shroompath/shroom_solution1.cc +++ b/_includes/source_code/code/37-PDP/shroompath/shroom_solution1.cc @@ -1,5 +1,4 @@ #include -using namespace std; typedef long long ll; const ll mod = 1000000007; diff --git a/_includes/source_code/code/37-PDP/shroompath/shroom_solution2.cc b/_includes/source_code/code/37-PDP/shroompath/shroom_solution2.cc index 427a7154..d15120f0 100755 --- a/_includes/source_code/code/37-PDP/shroompath/shroom_solution2.cc +++ b/_includes/source_code/code/37-PDP/shroompath/shroom_solution2.cc @@ -1,5 +1,4 @@ #include -using namespace std; typedef long long ll; const ll mod = 1000000007; diff --git a/_includes/source_code/code/37-PDP/shroompath/shroom_solution3_math.cc b/_includes/source_code/code/37-PDP/shroompath/shroom_solution3_math.cc index d72e246d..f2eab902 100755 --- a/_includes/source_code/code/37-PDP/shroompath/shroom_solution3_math.cc +++ b/_includes/source_code/code/37-PDP/shroompath/shroom_solution3_math.cc @@ -1,5 +1,4 @@ #include -using namespace std; typedef long long ll; const ll mod = 1000000007; @@ -26,7 +25,7 @@ long calc(int s,int x,int y){ }else{ ll w = f(B); //το w πρέπει να είναι άρτιος ώστε να μπορεί να διαιρεθεί με το 2 - if(w & 1)w+=mod;//μετατροπή του w σε ισοδύναμο άρτιο (ως προς mod) + if(w & 1)w+=mod;//αν w περιττός, μετέτρεψε το σε ισοδύναμο (ως προς mod) άρτιο return (p(B-1) + w/2+1)%mod; } } diff --git a/contests/_37-PDP/b-cauldron-solution.md b/contests/_37-PDP/b-cauldron-solution.md index 3f4b7ccd..fe15e677 100755 --- a/contests/_37-PDP/b-cauldron-solution.md +++ b/contests/_37-PDP/b-cauldron-solution.md @@ -22,15 +22,16 @@ $$2^N$$, αφού για κάθε βάζο έχουμε $$2$$ επιλογές: Ένας τρόπος να βρεθούν όλοι οι συνδυασμοί, είναι με τη χρήση αναδρομής: {% include code.md solution_name='cauldron_brute_recurse.cc' start=11 end=19 %} +Ολόκληρος ο κώδικας [εδώ]({% include link_to_source.md solution_name='cauldron_brute_recurse.cc' %}). -Ένας διαφορετικός τρόπος να βρούμε όλους τους συνδυασμούς, είναι να απαριθμήσουμε σε ένα βρόγχο -με μια μεταβλητή $$s$$, όλους τους αριθμούς από $$0$$ έως και $$2^N-1$$ -(ο $$2^N-1$$ στο δυαδικό σύστημα απεικονίζεται με $$N$$ άσους) και σε κάθε επανάληψη ελέγχουμε αν το $$i$$ *bit* -είναι αναμμένο ($$1$$) οπότε θα χρησιμοποιήσουμε το αντίστοιχο βάζο, +Ένας διαφορετικός τρόπος είναι να απαριθμήσουμε με ένα βρόγχο στη +μεταβλητή $$s$$ από το $$0$$ (κανένα βάζο) έως και το $$2^N-1$$ (όλα τα βάζα). +Ο αριθμός $$2^N-1$$ στο δυαδικό σύστημα απεικονίζεται με $$N$$ άσους και σε κάθε επανάληψη +ελέγχουμε αν το $$i$$-οστό *bit* είναι αναμμένο ($$1$$) οπότε θα χρησιμοποιήσουμε το αντίστοιχο βάζο, ή σβηστό ($$0$$) οπότε δεν θα το χρησιμοποιήσουμε. -{% include code.md solution_name='cauldron_brute.cc' start=21 end=32 %} - +{% include code.md solution_name='cauldron_brute.cc' start=20 end=31 %} +Ολόκληρος ο κώδικας [εδώ]({% include link_to_source.md solution_name='cauldron_brute.cc' %}). Η λύση αυτή χρειάζεται $$\mathcal{O}(N \cdot 2^N)$$ χρόνο, διότι για κάθε ένα συνδυασμό, ελέγχουμε τα $$N$$ *bits* του. ## Υποπρόβλημα 2 ($$c \le 0$$) @@ -48,10 +49,11 @@ $$2^N$$, αφού για κάθε βάζο έχουμε $$2$$ επιλογές: Όπως και στο προηγούμενο υποπρόβλημα, θα αποφασίσουμε από το $$c$$ αν θα χρησιμοποιήσουμε βάζα ή όχι. Αν το $$c$$ είναι θετικό, τότε θέλουμε όσα περισσότερα βάζα μπορούμε να χρησιμοποιήσουμε (ώστε να κερδίσουμε πολλά $$c$$). -Ο χρόνος που απαιτείται, είναι και σε αυτό το υποπρόβλημα $$\mathcal{O}(1)$$ καθώς αρκεί να διαβάσουμε την ποσότητα +Ο χρόνος που απαιτείται σε αυτό το υποπρόβλημα, είναι $$\mathcal{O}(1)$$, καθώς αρκεί να διαβάσουμε την ποσότητα μόνο ενός βάζου για να υπολογίσουμε την απάντηση. -{% include code.md solution_name='cauldron_subtask3.cc' start=15 end=21 %} +{% include code.md solution_name='cauldron_subtask3.cc' start=16 end=20 %} +Ολόκληρος ο κώδικας [εδώ]({% include link_to_source.md solution_name='cauldron_subtask3.cc' %}). ## Πλήρης λύση @@ -60,6 +62,7 @@ $$2^N$$, αφού για κάθε βάζο έχουμε $$2$$ επιλογές: καθώς θα καταναλώσει τη μικρότερη ποσότητα μαγικού νερού, αφήνοντας το υπόλοιπο μαγικό νερό για τα υπόλοιπα βάζα. Ταξινομούμε τα βάζα με το $$w_i$$, και χρησιμοποιούμε τα μικρότερα βάζα που η συνολική τους ποσότητα να μην ξεπεράσει το $$K$$. -O συνολικός χρόνος της λύσης αυτής, είναι $$\mathcal{O}(N\cdot \log_2{N})$$ (λόγω της ταξινόμησης). {% include code.md solution_name='cauldron_correct.cc' start=19 end=29 %} +Ολόκληρος ο κώδικας [εδώ]({% include link_to_source.md solution_name='cauldron_correct.cc' %}). +O συνολικός χρόνος της λύσης αυτής, είναι $$\mathcal{O}(N\cdot \log_2{N})$$ (λόγω της ταξινόμησης). diff --git a/contests/_37-PDP/b-shroompath-solution.md b/contests/_37-PDP/b-shroompath-solution.md index 4f67c640..1e70cf06 100755 --- a/contests/_37-PDP/b-shroompath-solution.md +++ b/contests/_37-PDP/b-shroompath-solution.md @@ -4,7 +4,7 @@ codename: shroompath --- ## Επεξήγηση εκφώνησης -Έχουμε όλους τους δυνατούς συνδυασμούς των γραμμάτων **α** και **β** σε συμβολοσειρές μήκους $$1,2,3,\dots \infty$$. +Έχουμε όλους τους δυνατούς συνδυασμούς των γραμμάτων **α** και **β** σε συμβολοσειρές μήκους $$1,2,3,\dots$$ Για κάθε ξεχωριστό μήκος, οι συμβολοσειρές είναι ταξινομημένες αλφαβητικά. Όλες οι συμβολοσειρές που προκύπτουν, κολλάνε μεταξύ τους (χωρίς κενά ενδιάμεσα) παράγοντας μια ατέρμονη συμβολοσειρά. @@ -20,12 +20,12 @@ codename: shroompath (έστω $$A$$ γράμματα **α** ή $$B$$ γράμματα **β**), αρκεί να διαιρέσουμε το βάρος $$S$$ με το βάρος $$X$$ ή $$Y$$ *στρογγυλοποιώντας προς τα πάνω*, για να υπολογίσουμε τα $$A$$ και $$B$$. Στα μαθηματικά ο συμβολισμός για τη στρογγυλοποίηση προς τα πάνω είναι -$$A = \lceil S/X \rceil, B = \lceil S/Y \rceil$$. -H συνάρτηση ``ceil`` της βιβλιοθήκης ``cmath`` κάνει ακριβώς αυτή τη στρογγυλοποίηση. -Εναλλακτικά, στη ``c++`` γνωρίζουμε ότι η ακέραια διαίρεση αγνοεί τυχόν δεκαδικά ψηφία, οπότε για το $$A$$ +$$A = \lceil S/X \rceil, B = \lceil S/Y \rceil$$. + +Στη ``c++`` γνωρίζουμε ότι η ακέραια διαίρεση αγνοεί τυχόν δεκαδικά ψηφία, οπότε για το $$A$$, αρκεί να κάνουμε τον υπολογισμό $$ A = (S+X-1)/X$$ (δηλαδή αυξάνουμε τόσο το $$S$$, ώστε να αυξήσει το πηλίκο αν και μόνο αν η διαίρεση -του $$S$$ με το $$X$$ δεν είναι τέλεια). +του $$S$$ με το $$X$$ δεν είναι τέλεια)[^1]. ## Υποπρόβλημα 1 ($$ S\le 15 $$) @@ -39,6 +39,7 @@ H συνάρτηση ``ceil`` της βιβλιοθήκης ``cmath`` κάνει χαρακτήρων ``Z``. {% include code.md solution_name='shroom_brute1.cc' start=10 end=21 %} +Δείτε ολόκληρο τον κώδικα [εδώ]({% include link_to_source.md solution_name='shroom_brute1.cc' %}). Κατόπιν με τη χρήση της συνάρτησης ``search`` της βιβλιοθήκης ``algorithm`` βρίσκουμε την πρώτη θέση που ξεκινούν τα $$A$$ συνεχόμενα **α** ή τα $$B$$ συνεχόμενα **β** που αναζητούμε. @@ -49,14 +50,12 @@ H συνάρτηση ``ceil`` της βιβλιοθήκης ``cmath`` κάνει $$2$$ τιμές). Τα **α** και **β** μπορούν να θεωρηθούν ως οι αριθμοί $$0$$ και $$1$$ του δυαδικού συστήματος και η παραγόμενη συμβολοσειρά να είναι η αλληλουχία όλων των μη μηδενικών φυσικών αριθμών απεικονισμένων στο δυαδικό σύστημα. -**Με βρόγχο:** Γνωρίζοντας από την *παρατήρηση 2* το πλήθος των συμβολοσειρών, τις κατασκευάζουμε με βρόγχο. +**Με βρόγχο:** Χρησιμοποιώντας την *παρατήρηση 2*, μπορούμε να κατασκευάσουμε τις συμβολοσειρές με ένα βρόγχο ως εξής: {% include code.md solution_name='shroom_brute2.cc' start=10 end=14 %} -Η λύση χρειάζεται $$\mathcal{O}(S\cdot 2^S)$$ χρόνο. -Μπορείτε να βρείτε ολόκληρο τον κώδικα των δύο παραπάνω λύσεων -[εδώ (αναδρομικά)]({% include link_to_source.md solution_name='shroom_brute1.cc' %}) και -[εδώ (με βρόγχο)]({% include link_to_source.md solution_name='shroom_brute2.cc' %}). +Μπορείτε να βρείτε ολόκληρο τον κώδικα [εδώ]({% include link_to_source.md solution_name='shroom_brute2.cc' %}). +Η λύση με αναδρομή ή βρόγχο, χρειάζεται $$\mathcal{O}(S\cdot 2^S)$$ χρόνο. ## Υποπρόβλημα 2 ($$ Χ\gt Y $$) @@ -75,7 +74,7 @@ $$2$$ τιμές). Τα **α** και **β** μπορούν να θεωρηθο τις συμβολοσειρές παρά μόνο να υπολογίσουμε πόσοι χαρακτήρες υπήρξαν σε όλα τα προηγούμενα μήκη συνδυασμών και σε ποιά θέση συγκεντρώσαμε τα απαραίτητα **α**. -{% include code.md solution_name='shroom_only_a.cc' start=8 end=17 %} +{% include code.md solution_name='shroom_only_a.cc' start=7 end=16 %} Ο χρόνος που χρειάζεται αυτή η λύση είναι $$\mathcal{O}(S)$$. Ολόκληρος ο κώδικας [εδώ]({% include link_to_source.md solution_name='shroom_only_a.cc' %}). @@ -92,7 +91,7 @@ $$2$$ τιμές). Τα **α** και **β** μπορούν να θεωρηθο Μεγάλος συνδυασμός β -{% include code.md solution_name='shroom_only_b.cc' start=8 end=18 %} +{% include code.md solution_name='shroom_only_b.cc' start=7 end=16 %} Ο χρόνος που χρειάζεται η λύση αυτή είναι $$\mathcal{O}(S)$$. Ολόκληρος ο κώδικας [εδώ]({% include link_to_source.md solution_name='shroom_only_b.cc' %}). @@ -107,7 +106,7 @@ $$2$$ τιμές). Τα **α** και **β** μπορούν να θεωρηθο οπότε υπολογίζουμε προοδευτικά τους συνδυασμούς **α** και **β** που συναντάμε και σταματάμε μόλις βρούμε την πρώτη λύση. -{% include code.md solution_name='shroom_solution1.cc' start=8 end=18 %} +{% include code.md solution_name='shroom_solution1.cc' start=7 end=17 %} Ολόκληρος ο κώδικας [εδώ]({% include link_to_source.md solution_name='shroom_solution1.cc' %}). Αν όμως αξιοποιήσουμε την πληροφορία ότι τα $$B$$ μανιτάρια τύπου **β** τα συναντάμε στις συμβολοσειρές μήκους $$B$$, είναι @@ -119,7 +118,7 @@ $$2$$ τιμές). Τα **α** και **β** μπορούν να θεωρηθο Ενώνοντας τις λύσεις των δύο προηγούμενων υποπροβλημάτων, έχουμε: -{% include code.md solution_name='shroom_solution2.cc' start=26 end=33 %} +{% include code.md solution_name='shroom_solution2.cc' start=25 end=32 %} Ολόκληρος ο κώδικας [εδώ]({% include link_to_source.md solution_name='shroom_solution2.cc' %}). Οι παραπάνω λύσεις χρειάζονται χρόνο $$\mathcal{O}(S)$$. @@ -134,27 +133,32 @@ $$p(k) = 2^{k+1}\cdot (k-1)+2$$ *Απόδειξη:*
Θα χρησιμοποιήσουμε επαγωγή.
-Για $$k=1$$, έχουμε $$p(1) = 2^{1+1}\cdot {1-1} +2 = 2$$ το οποίο ισχύει (έχουμε $$2$$ χαρακτήρες, ένα **α** και ένα **β** στους συνδυασμούς με μήκος $$1$$).
+Για $$k=1$$, έχουμε $$p(1) = 2^{1+1}\cdot (1-1) +2 = 2$$ το οποίο ισχύει (έχουμε $$2$$ χαρακτήρες, ένα **α** και ένα **β** στους συνδυασμούς με μήκος $$1$$).
Έστω ότι ισχύει για κάποιο $$k$$, δηλαδή $$p(k) = 2^{k+1}\cdot (k-1)+2$$,
-θα αποδείξουμε ότι ισχύει και για το $$k+1$$, δηλαδή:
-$$p(k+1)=2^{(k+1)+1}\cdot ((k+1)-1)+2 =2^{k+2}\cdot k + 2$$.
+θα αποδείξουμε ότι ισχύει και για το $$k+1$$, δηλαδή: + +$$p(k+1)=2^{(k+1)+1}\cdot ((k+1)-1)+2 =2^{k+2}\cdot k + 2$$ + +Γνωρίζουμε ότι -Γνωρίζουμε ότι
$$\begin{aligned} -p(k+1) =\\ -p(k) + f(k+1) =\\ -2^{k+1}\cdot (k-1)+2 + 2^{k+1} \cdot (k+1)=\\ -2^{k+1}\cdot k - 2^{k+1} + 2 + 2^{k+1}\cdot k + 2^{k+1}=\\ -2^{k+1}\cdot k - \cancel{2^{k+1}} + 2 + 2^{k+1}\cdot k + \cancel{2^{k+1}}=\\ -2^{k+1}\cdot k + 2^{k+1}\cdot k + 2=\\ -2\cdot 2^{k+1} \cdot k + 2=\\ -2^{k+2}\cdot k +2 -\end{aligned}$$
+p(k+1) = p(k) + f(k+1)\\ +=2^{k+1}\cdot (k-1)+2 + 2^{k+1} \cdot (k+1)\\ +=2^{k+1}\cdot k - 2^{k+1} + 2 + 2^{k+1}\cdot k + 2^{k+1}\\ +=2^{k+1}\cdot k - \cancel{2^{k+1}} + 2 + 2^{k+1}\cdot k + \cancel{2^{k+1}}\\ +=2^{k+1}\cdot k + 2^{k+1}\cdot k + 2\\ +=2\cdot 2^{k+1} \cdot k + 2\\ +=2^{k+2}\cdot k +2 +\end{aligned}$$ + άρα καταλήγουμε ότι ισχύει η $$p(k+1)$$, άρα η σχέση μας ισχύει για όλα τα $$k\ge1$$. Ο υπολογισμός της δύναμης με τη συνάρτηση ``pow2`` στην παραπάνω λύση, χρειάζεται λογαριθμικό χρόνο ως προς τον εκθέτη (μέγιστος εκθέτης ο $$S$$), οπότε ο χρόνος που χρειάζεται συνολικά η λύση είναι $$\mathcal{O}(\log_2{S})$$. Ο σχετικός κώδικας ακολουθεί: -{% include code.md solution_name='shroom_solution3_math.cc' start=17 end=32 %} +{% include code.md solution_name='shroom_solution3_math.cc' start=16 end=31 %} Ολόκληρος ο κώδικας [εδώ]({% include link_to_source.md solution_name='shroom_solution3_math.cc' %}) + +[^1]: Υπάρχει και η συνάρτηση ``ceil`` στη ``c++`` που κάνει στρογγυλοποίηση προς τα πάνω. Βρίσκεται στη βιβλιοθήκη ``cmath``. + From 8f8fae0eb813a623132394dbe0befd81f1fc8de8 Mon Sep 17 00:00:00 2001 From: kbokis Date: Thu, 20 Mar 2025 17:12:36 +0200 Subject: [PATCH 3/5] math expression sroompath --- contests/_37-PDP/b-shroompath-solution.md | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/contests/_37-PDP/b-shroompath-solution.md b/contests/_37-PDP/b-shroompath-solution.md index 1e70cf06..e9189189 100755 --- a/contests/_37-PDP/b-shroompath-solution.md +++ b/contests/_37-PDP/b-shroompath-solution.md @@ -142,13 +142,13 @@ $$p(k+1)=2^{(k+1)+1}\cdot ((k+1)-1)+2 =2^{k+2}\cdot k + 2$$ Γνωρίζουμε ότι $$\begin{aligned} -p(k+1) = p(k) + f(k+1)\\ -=2^{k+1}\cdot (k-1)+2 + 2^{k+1} \cdot (k+1)\\ -=2^{k+1}\cdot k - 2^{k+1} + 2 + 2^{k+1}\cdot k + 2^{k+1}\\ -=2^{k+1}\cdot k - \cancel{2^{k+1}} + 2 + 2^{k+1}\cdot k + \cancel{2^{k+1}}\\ -=2^{k+1}\cdot k + 2^{k+1}\cdot k + 2\\ -=2\cdot 2^{k+1} \cdot k + 2\\ -=2^{k+2}\cdot k +2 +p(k+1) &= p(k) + f(k+1)\\ +&=2^{k+1}\cdot (k-1)+2 + 2^{k+1} \cdot (k+1)\\ +&=2^{k+1}\cdot k - 2^{k+1} + 2 + 2^{k+1}\cdot k + 2^{k+1}\\ +&=2^{k+1}\cdot k - \cancel{2^{k+1}} + 2 + 2^{k+1}\cdot k + \cancel{2^{k+1}}\\ +&=2^{k+1}\cdot k + 2^{k+1}\cdot k + 2\\ +&=2\cdot 2^{k+1} \cdot k + 2\\ +&=2^{k+2}\cdot k +2 \end{aligned}$$ άρα καταλήγουμε ότι ισχύει η $$p(k+1)$$, άρα η σχέση μας ισχύει για όλα τα $$k\ge1$$. From 28fb0823ab0de484a69f4ac335f3b2a39ea1fb2a Mon Sep 17 00:00:00 2001 From: Dim131 Date: Sat, 22 Mar 2025 01:21:59 +0000 Subject: [PATCH 4/5] Update b-cauldron-solution.md --- contests/_37-PDP/b-cauldron-solution.md | 3 --- 1 file changed, 3 deletions(-) diff --git a/contests/_37-PDP/b-cauldron-solution.md b/contests/_37-PDP/b-cauldron-solution.md index fe15e677..e782a1ed 100755 --- a/contests/_37-PDP/b-cauldron-solution.md +++ b/contests/_37-PDP/b-cauldron-solution.md @@ -42,9 +42,6 @@ $$2^N$$, αφού για κάθε βάζο έχουμε $$2$$ επιλογές: (αν είναι μηδενική), δεν χρειάζεται να πάρουμε κανένα βάζο. Ο χρόνος που απαιτείται είναι $$\mathcal{O}(1)$$ (σταθερός) καθώς δεν επηρεάζεται από το $$N$$. - -{% include code.md solution_name='cauldron_subtask2.cc' start=10 end=11 %} - ## Υποπρόβλημα 3 (όλα τα βάζα είναι ίδια) Όπως και στο προηγούμενο υποπρόβλημα, θα αποφασίσουμε από το $$c$$ αν θα χρησιμοποιήσουμε βάζα ή όχι. Αν το $$c$$ From f003d928d893e060ca789a35b1299ace00676c29 Mon Sep 17 00:00:00 2001 From: Dim131 Date: Sat, 22 Mar 2025 01:29:15 +0000 Subject: [PATCH 5/5] Update b-shroompath-solution.md --- contests/_37-PDP/b-shroompath-solution.md | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/contests/_37-PDP/b-shroompath-solution.md b/contests/_37-PDP/b-shroompath-solution.md index e9189189..40fc5566 100755 --- a/contests/_37-PDP/b-shroompath-solution.md +++ b/contests/_37-PDP/b-shroompath-solution.md @@ -131,13 +131,10 @@ $$f(k) = 2^k \cdot k$$. Ο υπολογισμός του συνόλου των Η συνάρτηση αυτή μπορεί να υπολογισθεί με $$p(k) = 2^{k+1}\cdot (k-1)+2$$ -*Απόδειξη:*
-Θα χρησιμοποιήσουμε επαγωγή.
-Για $$k=1$$, έχουμε $$p(1) = 2^{1+1}\cdot (1-1) +2 = 2$$ το οποίο ισχύει (έχουμε $$2$$ χαρακτήρες, ένα **α** και ένα **β** στους συνδυασμούς με μήκος $$1$$).
-Έστω ότι ισχύει για κάποιο $$k$$, δηλαδή $$p(k) = 2^{k+1}\cdot (k-1)+2$$,
-θα αποδείξουμε ότι ισχύει και για το $$k+1$$, δηλαδή: +*Απόδειξη:* Θα χρησιμοποιήσουμε επαγωγή. Για $$k=1$$, έχουμε $$p(1) = 2^{1+1}\cdot (1-1) +2 = 2$$ το οποίο ισχύει (έχουμε $$2$$ χαρακτήρες, ένα **α** και ένα **β** στους συνδυασμούς με μήκος $$1$$).
+Έστω ότι ισχύει για κάποιο $$k$$, δηλαδή $$p(k) = 2^{k+1}\cdot (k-1)+2$$, θα αποδείξουμε ότι ισχύει και για το $$k+1$$, δηλαδή: -$$p(k+1)=2^{(k+1)+1}\cdot ((k+1)-1)+2 =2^{k+2}\cdot k + 2$$ +$$p(k+1)=2^{(k+1)+1}\cdot ((k+1)-1)+2 =2^{k+2}\cdot k + 2.$$ Γνωρίζουμε ότι