Submission #285107

#TimeUsernameProblemLanguageResultExecution timeMemory
285107user202729Paint By Numbers (IOI16_paint)C++17
100 / 100
267 ms7928 KiB
// moreflags=grader.cpp #include "paint.h" // 15 // It's weird that the wrong code can pass many subtasks. // !? #include <cstdlib> #include<climits> #if not LOCAL #define NDEBUG 1 #endif #include<cassert> struct D{ std::vector<int> nextFail; // first >=index, or INT_MAX D(std::string const& s, auto satisfy): nextFail(s.size()){ int cur=INT_MAX; for(int i=(int)s.size(); i--;){ if(not satisfy(s[i])) cur=i; nextFail[i]=cur; } } bool allSatisfy(int left, int right) const{ assert(left<right); return nextFail[left]>=right; } }; std::string solve_puzzle(std::string s, std::vector<int> c) { D checkx{s, [&](char ch){return ch!='_';}}; std::vector<std::vector<bool>> matchLeft(c.size()+1, std::vector<bool>(s.size()+1)); // [lenc][lens] for(int lens=0;; ++lens){ matchLeft[0][lens]=true; if(lens==(int)s.size()) break; if(s[lens]=='X') break; } for(int lenc=1; lenc<=(int)c.size(); ++lenc){ auto const curc=c[lenc-1]; for(int lens=1; lens<=(int)s.size(); ++lens){ matchLeft[lenc][lens]=( matchLeft[lenc][lens-1] and s[lens-1]!='X' ) or ( lens>=curc and checkx.allSatisfy(lens-curc, lens) and (lens==curc ? lenc==1: (s[lens-curc-1]!='X' and matchLeft[lenc-1][lens-curc-1])) ); } } std::vector<std::vector<bool>> matchRight(c.size()+1, std::vector<bool>(s.size()+1)); // [lenc][lens] (from the right) for(int lens=0;; ++lens){ matchRight[0][lens]=true; if(lens==(int)s.size()) break; if(s.rbegin()[lens]=='X') break; } for(int lenc=1; lenc<=(int)c.size(); ++lenc){ auto const curc=c.rbegin()[lenc-1]; for(int lens=1; lens<=(int)s.size(); ++lens){ matchRight[lenc][lens]=( matchRight[lenc][lens-1] and s.rbegin()[lens-1]!='X' ) or ( lens>=curc and checkx.allSatisfy((int)s.size()-lens, (int)s.size()-lens+curc) and (lens==curc ? lenc==1: (s.rbegin()[lens-curc-1]!='X' and matchRight[lenc-1][lens-curc-1])) ); } } std::string result(s.size(), 0); char const crossable=1, blankable=2; for(int index=0; index<(int)s.size(); ++index){ for(int lenc=0; lenc<=(int)c.size(); ++lenc){ if(s[index]=='_' // assumes that there always exists a solution or ( s[index]=='.' and matchLeft[lenc][index] and matchRight[c.size()-lenc][(int)s.size()-index-1] )){ result[index]|=blankable; break; } } } std::vector<int> fillTemp(s.size()); auto const fillx=[&](int left, int right){ assert(left<right); fillTemp[left]=std::max(fillTemp[left], right); }; for(int indexc=0; indexc<(int)c.size(); ++indexc){ auto const curc=c[indexc]; for(int index=curc; index<=(int)s.size(); ++index) if( (index==(int)s.size() ? indexc==(int)c.size()-1 : ( matchRight[c.size()-1-indexc][s.size()-index-1] and s[index]!='X')) and (index-curc==0 ? indexc==0 : ( matchLeft[indexc][index-curc-1] and s[index-curc-1]!='X')) and checkx.allSatisfy(index-curc, index) ){ //result[index]|=blankable; //result[index-curc-1]|=blankable; fillx(index-curc, index); } } for(int index=0; index<(int)s.size(); ++index){ if(fillTemp[index]>index){ result[index]|=crossable; if(index==(int)s.size()-1) break; fillTemp[index+1]=std::max(fillTemp[index+1], fillTemp[index]); } } for(auto& it: result){ assert(it<=(crossable|blankable)); auto const pattern="#X_?"; assert(pattern[int(crossable)]=='X'); assert(pattern[int(blankable)]=='_'); assert(pattern[int(crossable|blankable)]=='?'); it=pattern[int(it)]; } return result; }

Compilation message (stderr)

paint.cpp:16:26: warning: use of 'auto' in parameter declaration only available with '-fconcepts'
   16 |  D(std::string const& s, auto satisfy): nextFail(s.size()){
      |                          ^~~~
#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...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...