제출 #1234342

#제출 시각아이디문제언어결과실행 시간메모리
1234342nikulidLongest Trip (IOI23_longesttrip)C++20
15 / 100
6 ms416 KiB
#include "longesttrip.h" #include <queue> #include <iostream> //#include <assert.h> using namespace std; #define pb push_back #define dcerr if(1==0)cerr vector<int> longest_trip(int n, int d){ vector<int> ans; if(d==2){ // surely there still exists a round trip... // why is this screaming linked list :( vector<int> starts; if(!are_connected({0}, {n-1})){ starts.pb(0); } for(int i=1; i<n; i++){ if(!are_connected({i-1}, {i})){ starts.pb(i); } } if(starts.size()==0){ d=3; // go do the easy case (0,1,2,...) } else{ // we certainly have breaks somewhere. starts.pb(starts[0]+n); bool forwards=false; for(int j=0; j<starts.size()-1; j++){ forwards = !forwards; if(forwards){ // forwards for(int i=starts[j]; i<starts[j+1]; i++){ ans.pb(i%n); } } else{ // backwards for(int i=starts[j+1]-1; i>starts[j]-1; i--){ ans.pb(i%n); } } } } } if(d==3){ for(int i=0; i<n; i++){ ans.pb(i); } } if(d==1){ // the boss fight vector<int> link(n, -1); int start1, start2, end1, end2; int a,b,c; queue<int> q; a=are_connected({0}, {1}); b=are_connected({1}, {2}); c=are_connected({0}, {2}); if(a){ start1=0; link[0]=1; end1=1; } else if(b){ start1=1; link[1]=2; end1=2; } else if(c){ start1=0; link[0]=2; end1=2; } for(int i=0; i<n; i++){ if(i!=start1 && i!=end1){ q.push(i); } } a=-1;b=-1;c=-1; start2=-1;end2=-1; while(!q.empty()){ // a a=end1; // b if(start2==-1){ b=q.front(); q.pop(); start2=b; end2=b; } // c if(c==-1 && !q.empty()){ c=q.front(); q.pop(); } // at this point: b and c are both real values. //assert(a!=b); //assert(b!=c); //assert(a!=c); if(are_connected({a}, {b})){ // a-b (join the lists) link[a]=b; end1=end2; a=end2; start2=-1; end2=-1; b=-1; } else if(c!=-1 && are_connected({a}, {c})){ // a-c (go to list1) end1=c; link[a]=c; c=-1; } else if(c!=-1){ //|| are_connected({b}, {c})){ // b-c (go to list2) start2=c; link[c]=b; b=c; c=-1; } } // recall that: // a = the end of the first string // b = the start of the second string (possibly -1) // c = the new value to add (possibly -1) // if c has a value, then we aren't really done... if(c != -1){ // we aren't done // c being something means that b is nothing (!) if(are_connected({a}, {c})){ link[a]=c; end1=c; a=c; c=-1; } else{ start2=c; end2=c; } } // <--- DEBUGGING ---> dcerr<<"start1, end1: "<<start1<<", "<<end1<<"\n"; dcerr<<"start2, end2: "<<start2<<", "<<end2<<"\n"; int cur=start1; vector<int> ans1={start1}; while(link[cur] != -1){ cur = link[cur]; ans1.pb(cur); } if(start2==-1){ return ans1; } // else... // in this case we have to do some freaky shit cur=start2; vector<int> ans2={start2}; while(link[cur] != -1){ cur = link[cur]; ans2.pb(cur); } // ans1+ans2=everything (I hope) if(!are_connected(ans1, ans2)){ if(ans1.size() >= ans2.size()){ return ans1; } else{ return ans2; } } dcerr<<"$ they are connected...\n"; // oh shit they're connected... vector<int> finalanswer; vector<int> secondary_endpoints = {start2}; if(start2 != end2) secondary_endpoints.pb(end2); if(are_connected({start1, end1}, secondary_endpoints)){ // simple case. if(are_connected({end1}, {start2})){ dcerr<<"$ simple case 1.\n"; for(int i=0; i<ans1.size(); i++) finalanswer.pb(ans1[i]); for(int i=0; i<ans2.size(); i++) finalanswer.pb(ans2[i]); } else if(are_connected({end1}, {end2})){ for(int i=0; i<ans1.size(); i++) finalanswer.pb(ans1[i]); for(int i=ans2.size()-1; i>-1; i--) finalanswer.pb(ans2[i]); } else if(are_connected({start1}, {start2})){ for(int i=ans1.size()-1; i>-1; i--) finalanswer.pb(ans1[i]); for(int i=0; i<ans2.size(); i++) finalanswer.pb(ans2[i]); } else{ //start1, end2 for(int i=ans1.size()-1; i>-1; i--) finalanswer.pb(ans1[i]); for(int i=ans2.size()-1; i>-1; i--) finalanswer.pb(ans2[i]); } return finalanswer; } dcerr<<"$ not as simple.\n"; // not simple case. FUUUUUCCKKK // both lists are cyclic... binary search? idk int s1=ans1.size(),s2=ans2.size(); // find the link in ans1... int a1_connector; // ...using b*nary search (ew) int l=0, r=s1-1, m=(r+l)/2; vector<int> curvec(2,0); for(int i=l; i<=m; i++) curvec.pb(ans1[i]); while(curvec.size()>1){ if(are_connected({curvec}, {ans2})){ l = m+1; } else{ r = m; } curvec.clear(); for(int i=l; i<=m; i++) curvec.pb(ans1[i]); } // now we have curvec.size()==1 a1_connector = l; curvec.clear(); // time to find a2_connector. int a2_connector; l=0; r=s2-1; m=(r+l/2); for(int i=l; i<=m; i++) curvec.pb(ans1[i]); while(curvec.size()>1){ if(are_connected({curvec}, {ans2})){ l = m+1; } else{ r = m; } curvec.clear(); for(int i=l; i<=m; i++) curvec.pb(ans1[i]); } a2_connector = l; // now we should have everything we need :) for(int i=a1_connector+1; i<a1_connector+s1+1; i++){ finalanswer.pb(ans1[i%s1]); } for(int i=a2_connector+1; i<a2_connector+s2+1; i++){ finalanswer.pb(ans2[i%s2]); } return finalanswer; } 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...