제출 #1246773

#제출 시각아이디문제언어결과실행 시간메모리
1246773vht2025Fliper (COCI22_fliper)C++20
0 / 110
306 ms76868 KiB
#include <bits/stdc++.h> using namespace std; using ll = long long; const int DIR = 4; // 0=E 1=S 2=W 3=N int refl[2][DIR] = { {3,2,1,0}, {1,0,3,2} }; // '/' , '\' int opp(int d){ return d^2; } struct Ob{ int x,y; char t; }; struct Adj{ int to,id; }; int main(){ ios::sync_with_stdio(false); cin.tie(nullptr); int n; if(!(cin>>n)) return 0; vector<Ob> a(n); for(auto &o:a) cin>>o.x>>o.y>>o.t; /* step A: nearest neighbours E,W,N,S */ vector<array<int,DIR>> nxt(n); const int NIL=-1; unordered_map<ll, vector<pair<int,int>>> rows,cols; rows.reserve(n*2); cols.reserve(n*2); auto key=[&](int p){ return (ll)p+2000000001LL; }; // shift to avoid neg for(int i=0;i<n;++i){ rows[key(a[i].y)].push_back({a[i].x,i}); cols[key(a[i].x)].push_back({a[i].y,i}); } for(auto &v:rows){ auto &vec=v.second; sort(vec.begin(),vec.end()); for(int k=0;k<(int)vec.size();++k){ int id=vec[k].second; nxt[id][2] = (k? vec[k-1].second:NIL); nxt[id][0] = (k+1<(int)vec.size()?vec[k+1].second:NIL); } } for(auto &v:cols){ auto &vec=v.second; sort(vec.begin(),vec.end()); for(int k=0;k<(int)vec.size();++k){ int id=vec[k].second; nxt[id][3] = (k? vec[k-1].second:NIL); nxt[id][1] = (k+1<(int)vec.size()?vec[k+1].second:NIL); } } /* step B: build functional graph of states */ int S = 4*n; auto idx=[&](int i,int d){ return i*4+d; }; vector<int> go(S,-1); for(int i=0;i<n;++i){ int tp=(a[i].t=='\\'); for(int d=0;d<DIR;++d){ int out=refl[tp][d]; int j=nxt[i][out]; if(j==NIL) continue; go[idx(i,d)] = idx(j, opp(out)); } } /* step C: detect cycles */ vector<int> color(S,0), cycId(S,-1); vector<int> cycLen; int cid=0; vector<int> st; bool fail=false; for(int v=0;v<S && !fail;++v) if(!color[v]){ int x=v; while(x!=-1 && !color[x]){ color[x]=1; st.push_back(x); x=go[x]; } if(x!=-1 && color[x]==1){ vector<int> cyc; int y; do{ y=st.back(); st.pop_back(); cyc.push_back(y);}while(y!=x); if(cyc.size()%8){ fail=true; break; } for(int s:cyc) cycId[s]=cid; cycLen.push_back(cyc.size()); ++cid; } while(!st.empty()){ color[st.back()]=2; st.pop_back(); } } if(fail){ cout<<-1<<"\n"; return 0; } const int DUMMY = cid; int V=cid+1; /* step D: build edge list */ vector<vector<Adj>> g(V); struct Edge{ int u,v,obs; }; vector<Edge> edges; edges.reserve(n); for(int i=0;i<n;++i){ int idA=-1,idB=-1; if(a[i].t=='/'){ int sa0=cycId[idx(i,0)], sa1=cycId[idx(i,3)]; int sb0=cycId[idx(i,1)], sb1=cycId[idx(i,2)]; idA = (sa0!=-1?sa0:sa1); idB = (sb0!=-1?sb0:sb1); }else{ int sa0=cycId[idx(i,0)], sa1=cycId[idx(i,1)]; int sb0=cycId[idx(i,2)], sb1=cycId[idx(i,3)]; idA = (sa0!=-1?sa0:sa1); idB = (sb0!=-1?sb0:sb1); } if(idA==-1) idA=DUMMY; if(idB==-1) idB=DUMMY; edges.push_back({idA,idB,i}); int eid=edges.size()-1; g[idA].push_back({idB,eid}); g[idB].push_back({idA,eid}); // always add twice } /* step E: degree check */ for(int v=0; v<cid; ++v) if(g[v].size()%8){ cout<<-1<<"\n"; return 0; } /* helper: generic Euler colouring */ auto euler_colour=[&](const vector<char>& useMask, vector<int>& res, int baseCol){ int m=edges.size(); vector<char> used(m,0); vector<size_t> it(V,0); for(int start=0; start<V; ++start){ if(start!=DUMMY && g[start].empty()) continue; if(it[start]==g[start].size()) continue; vector<int> vs, es; vs.push_back(start); while(!vs.empty()){ int v=vs.back(); while(it[v]<g[v].size() && (used[g[v][it[v]].id] || !useMask[g[v][it[v]].id])) ++it[v]; if(it[v]==g[v].size()){ if(!es.empty()){ res[es.back()] = baseCol + (es.size()%2); es.pop_back(); } vs.pop_back(); }else{ auto e=g[v][it[v]++]; used[e.id]=1; vs.push_back(e.to); es.push_back(e.id); } } } }; /* step F: three phases */ int m=edges.size(); vector<int> col(m,-1); vector<char> all(m,1); euler_colour(all,col,0); // first pass: 0/1 vector<char> white(m,0), black(m,0); for(int i=0;i<m;++i) (col[i]==0?white:black)[i]=1; euler_colour(white,col,1); // 1/2 euler_colour(black,col,3); // 3/4 /* step G: output */ for(int i=0;i<m;++i) if(col[i]<1||col[i]>4){ cout<<-1<<"\n"; return 0; } vector<int> ans(n); for(int i=0;i<m;++i) ans[edges[i].obs]=col[i]; for(int i=0;i<n;++i) cout<<ans[i]<<(i+1==n?'\n':' '); return 0; }
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...