2018 ACM-ICPC, Syrian Collegiate Programming Contest
水题
水题
C Portals
思路:并查集维护连通性
代码:
//#pragma GCC optimize(3) //#pragma comment(linker, "/STACK:102400000,102400000") //c++ // #pragma GCC diagnostic error "-std=c++11" // #pragma comment(linker, "/stack:200000000") // #pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native") // #pragma GCC optimize("-fdelete-null-pointer-checks,inline-functions-called-once,-funsafe-loop-optimizations,-fexpensive-optimizations,-foptimize-sibling-calls,-ftree-switch-conversion,-finline-small-functions,inline-small-functions,-frerun-cse-after-loop,-fhoist-adjacent-loads,-findirect-inlining,-freorder-functions,no-stack-protector,-fpartial-inlining,-fsched-interblock,-fcse-follow-jumps,-fcse-skip-blocks,-falign-functions,-fstrict-overflow,-fstrict-aliasing,-fschedule-insns2,-ftree-tail-merge,inline-functions,-fschedule-insns,-freorder-blocks,-fwhole-program,-funroll-loops,-fthread-jumps,-fcrossjumping,-fcaller-saves,-fdevirtualize,-falign-labels,-falign-loops,-falign-jumps,unroll-loops,-fsched-spec,-ffast-math,Ofast,inline,-fgcse,-fgcse-lm,-fipa-sra,-ftree-pre,-ftree-vrp,-fpeephole2",3) #include <algorithm> #include <iterator> #include <iostream> #include <cstring> #include <cstdlib> #include <iomanip> #include <bitset> #include <cctype> #include <cstdio> #include <string> #include <vector> #include <stack> #include <cmath> #include <queue> #include <list> #include <map> #include <set> #include <cassert> using namespace std; #define lson (l , mid , rt << 1) #define rson (mid + 1 , r , rt << 1 | 1) #define debug(x) cerr << #x << " = " << x << "\n"; #define pb push_back #define pq priority_queue typedef long long ll; typedef unsigned long long ull; //typedef __int128 bll; typedef pair<ll ,ll > pll; typedef pair<int ,int > pii; typedef pair<int,pii> p3; //priority_queue<int> q;//这是一个大根堆q //priority_queue<int,vector<int>,greater<int> >q;//这是一个小根堆q #define fi first #define se second //#define endl '\n' #define OKC ios::sync_with_stdio(false);cin.tie(0) #define FT(A,B,C) for(int A=B;A <= C;++A) //用来压行 #define REP(i , j , k) for(int i = j ; i < k ; ++i) #define max3(a,b,c) max(max(a,b), c); #define min3(a,b,c) min(min(a,b), c); //priority_queue<int ,vector<int>, greater<int> >que; const ll mos = 0x7FFFFFFF; //2147483647 const ll nmos = 0x80000000; //-2147483648 const int inf = 0x3f3f3f3f; const ll inff = 0x3f3f3f3f3f3f3f3f; //18 const int mod = 1e8+7; const double esp = 1e-8; const double PI=acos(-1.0); const double PHI=0.61803399; //黄金分割点 const double tPHI=0.38196601; template<typename T> inline T read(T&x){ x=0;int f=0;char ch=getchar(); while (ch<'0'||ch>'9') f|=(ch=='-'),ch=getchar(); while (ch>='0'&&ch<='9') x=x*10+ch-'0',ch=getchar(); return x=f?-x:x; } /*-----------------------showtime----------------------*/ const int maxn = 2e6+9; char str[maxn]; int fa[maxn]; int find(int x){ if(fa[x] == x)return x; return fa[x] = find(fa[x]); } void uni(int x,int y){ int fx = find(x); int fy = find(y); if(fx == fy) return ; fa[fx] = fy; } int main(){ freopen("portals.in", "r", stdin); int T; scanf("%d", &T); while(T--){ int n; scanf("%d%s", &n, str); for(int i=0; i<=n; i++) fa[i] = i; int s,t; /* for(int i=0; i<n; i++){ if(str[i] == 's'){ s = i; str[i] = '.'; } if(str[i] == 'e'){ t = i; str[i] = '.'; } } */ for(int i=0; i<n; i++){ if(str[i] == 's'){ s = i; } if(str[i] == 'e'){ t = i; } if(str[i] == 'o'){ uni(i,n); if(i<n&&str[i+1] == '.')uni(i,i+1); } else if(str[i] == '.'){ if(i<n&&str[i+1] == '.')uni(i,i+1); if(i<n&&str[i+1] == 'o')uni(i,i+1); } } if(abs(s-t) == 1) { puts("-1"); continue; } int ans = inf, a[4]; for(int i=0; i<16; i++){ int m = i; for(int j=0; j<4; j++){ a[j] = m% 2; m = m/2; } int cnt = 0; int flag = 1; int tmp[2]; tmp[0] = tmp[1] = -1; if(s-1>=0&&str[s-1] =='.'){ if(a[0] == 0)cnt++; else { int f = find(s-1); tmp[0]=f; } } else if(s-1>=0&&str[s-1] == 'o'){ int f = find(s-1); tmp[0]=f; } if(s+1 < n && str[s+1] =='.'){ if(a[1] == 0)cnt++; else { int f = find(s+1); tmp[1]=f; } } else if(s+1<n && str[s+1] =='o'){ int f = find(s+1); tmp[1] = f; } //t if(t-1>=0&&str[t-1] =='.'){ if(a[2] == 0)cnt++; else { int f = find(t-1); if(f == tmp[0] || f == tmp[1])flag = 0; } } else if(t-1>=0&&str[t-1] == 'o'){ int f = find(t-1); if(f == tmp[0] || f == tmp[1])flag = 0; } if(t+1<n&&str[t+1] =='.'){ if(a[3] == 0)cnt++; else { int f = find(t+1); if(f == tmp[0] || f == tmp[1])flag = 0; } } else if(t+1<n&&str[t+1] == 'o'){ int f = find(t+1); if(f == tmp[0] || f == tmp[1])flag = 0; } if(flag) {ans = min(ans, cnt); if(ans == 1) debug(i); } } if(ans >= inf) puts("-1"); else printf("%d\n", ans); } return 0; }