2019ICPC 上海现场赛
网址:https://ac.nowcoder.com/acm/contest/4370
B. Prefix Code
阅读理解,用个set维护下就行
#include <stdio.h> #include <iostream> #include <cstring> #include <algorithm> #include <cmath> #include <queue> #include <map> #include <stack> #include <sstream> #include <set> // #pragma GCC optimize(2) //#define int long long #define ls u<<1 #define rs u<<1|1 #define rep(i,a,n) for(int i=a;i<=n;i++) #define REP(i,a,n) for(int i=a;i>=n;--i) #define rush() int T;scanf("%d",&T);for(int Ti=1;Ti<=T;++Ti) #define IOS ios::sync_with_stdio(0); cin.tie(0); cout.tie(0); #define mm(i,v) memset(i,v,sizeof i); #define mp(a, b) make_pair(a, b) #define pi acos(-1) #define fi first #define se second using namespace std; typedef long long ll; typedef double db; typedef pair<ll, ll > PII; priority_queue< PII, vector<PII>, greater<PII> > que; stringstream ssin; // ssin << string while ( ssin >> int) const ll LINF = 0x7fffffffffffffffll; const int N = 4e5 + 5, M = 4e5 + 5, mod = 1e9 + 7, INF = 0x3f3f3f3f; int _, n; string s, t; set<string>s1, s2; vector<string>vec; inline ll read() { char c=getchar();ll x=0,f=1; while(c<'0'||c>'9'){if(c=='-')f=-1; c=getchar();} while(c>='0'&&c<='9'){x=x*10+c-'0'; c=getchar();} return x*f; } int main() { #ifndef ONLINE_JUDGE freopen("in.txt","r",stdin); freopen("out.txt","w",stdout); #endif int cas = 0; _ = read(); while (_--) { s1.clear(); s2.clear(); vec.clear(); n = read(); bool f = 1; rep(i, 1, n) { cin >> s; if (s1.find(s) != s1.end()) f = 0; s1.insert(s); vec.push_back(s); } rep(i, 0, n - 1) { s = vec[i]; t.clear(); for (int i = 0; i < s.size() - 1; ++i) { t += s[i]; if (s1.find(t) != s1.end()) { f = 0; break; } if (!f) break; } if (!f) break; } printf("Case #%d: ", ++cas); if (f) puts("Yes"); else puts("No"); } // #ifndef ONLINE_JUDGE // system("pause"); // #endif }
K. Color Graph
二分图签到
题意可以转化为判奇环,可以发现n很小,二进制枚举每个点的状态,然后直接判断即可
#include <stdio.h> #include <iostream> #include <cstring> #include <algorithm> #include <cmath> #include <queue> #include <map> #include <stack> #include <sstream> #include <set> #pragma GCC optimize(2) //#define int long long #define mm(i,v) memset(i,v,sizeof i); #define mp(a, b) make_pair(a, b) #define pi acos(-1) #define fi first #define se second //你冷静一点,确认思路再敲!!! using namespace std; typedef long long ll; typedef pair<int, int > PII; priority_queue< PII, vector<PII>, greater<PII> > que; stringstream ssin; // ssin << string while ( ssin >> int) const int N = 500, mod = 1e9 + 9, INF = 0x3f3f3f3f; int t, n, m, idx, id, pos, Max; int e[N], h[N], ne[N], col[20]; bool flag; inline int read(){ char c=getchar();int x=0,f=1; while(c<'0'||c>'9'){if(c=='-')f=-1; c=getchar();} while(c>='0'&&c<='9'){x=x*10+c-'0'; c=getchar();} return x*f; } void add(int a, int b) { e[idx] = b; ne[idx] = h[a]; h[a] = idx++; } vector<PII> vec; int main() { cin >> t; while (t--) { vec.clear(); Max = -1; mm(h, -1); idx = 0; cin >> n >> m; for (int i = 1; i <= m; ++i) { int a, b; cin >> a >> b; vec.push_back(mp(a, b)); } for (pos = 0; pos <= (1 << n); ++pos) { mm(col, 0); flag = 1; for (int i = 1; i <= n; ++i) { if ((pos >> i) & 1 && !col[i]) { col[i] = 1; } } int ans = 0; for (int i = 0; i < vec.size(); ++i) { int x = vec[i].first, y = vec[i].second; if (col[x] != col[y]) ans++; } Max = max(Max, ans); } printf("Case #%d: %d\n", ++id, Max); } // system("pause"); return 0; }
E. Cave Escape
可以发现起点和终点并不影响选择的路径,所以只需要对点建边求最大生成树即可
#pragma GCC optimize(2) #include<bits/stdc++.h> using namespace std; const int man = 1e3+10; #define IOS ios::sync_with_stdio(0) template <typename T> inline T read(){T sum=0,fl=1;int ch=getchar(); for(;!isdigit(ch);ch=getchar())if(ch=='-')fl=-1; for(;isdigit(ch);ch=getchar())sum=sum*10+ch-'0'; return sum*fl;} template <typename T> inline void write(T x) {static int sta[35];int top=0; do{sta[top++]= x % 10, x /= 10;}while(x); while (top) putchar(sta[--top] + 48);} template<typename T>T gcd(T a, T b) {return b==0?a:gcd(b, a%b);} template<typename T>T exgcd(T a,T b,T &g,T &x,T &y){if(!b){g = a,x = 1,y = 0;} else {exgcd(b,a%b,g,y,x);y -= x*(a/b);}} #ifndef ONLINE_JUDGE #define debug(fmt, ...) {printf("debug ");printf(fmt,##__VA_ARGS__);puts("");} #else #define debug(fmt, ...) #endif typedef long long ll; const ll mod = 1e9+7; int x[man*man],fa[man*man],va[man][man]; int sz[man*man]; vector<pair<int,int> >A[10010]; int find(int x){ return x == fa[x] ? x : fa[x] = find(fa[x]); } /* int find(int x){ int p = x; while(p!=fa[p])p = fa[p]; while(x!=p){ int tp = fa[x]; fa[x] = p; x = tp; } return p; }*/ bool _union(int u,int v){ // cout << u << " 1\" " << v <<endl; u = find(u); v = find(v); // cout << u << " 2\" " << v << endl; if(u==v)return true; if(sz[u]>sz[v]){ sz[u] += sz[v]; fa[v] = u; }else fa[u] = v,sz[v] += sz[u]; return false; } int main() { #ifndef ONLINE_JUDGE //freopen("in.txt", "r", stdin); //freopen("out.txt","w",stdout); #endif int t; scanf("%d",&t); int T = 0; while(t--){ int n,m,s,a,b,c,p; for(int i = 0;i <= 10000;i++)A[i].clear(); scanf("%d%d%d%d%d%d",&n,&m,&s,&s,&s,&s); scanf("%d%d%d%d%d%d",x+1,x+2,&a,&b,&c,&p); fa[1] = 1; fa[2] = 2; for(int i = 3;i <= n*m;i++){ fa[i] = i; sz[i] = 1; x[i] = (a*x[i-1] + b*x[i-2] + c)%p; } int cnt = 0; for(int i = 1;i <= n;i++){ for(int j = 1;j <= m;j++){ va[i][j] = x[(i-1)*m + j]; if(!va[i][j])continue; if(i>1&&va[i-1][j])A[va[i][j]*va[i-1][j]].push_back(make_pair((i-1)*m + j,(i-2)*m + j)); if(j>1&&va[i][j-1])A[va[i][j]*va[i][j-1]].push_back(make_pair((i-1)*m + j,(i-1)*m + j - 1)); } } ll ans = 0; int res = 0; for(int j = 10000;j >= 0;j--){ for(int i = 0;i < A[j].size();i++){ int u = A[j][i].first; int v = A[j][i].second; //cout << A[i].w << endl; // if(!_union(u,v)){ // } if (find(u) == find(v)) continue; int pa = find(u), pb = find(v); fa[pa] = pb; ans += j; res++; if(res==n*m-1)break; } if(res==n*m-1)break; } printf("Case #%d: %lld\n",++T,ans); } return 0; }
H. Tree Partition
二分+贪心
对于每棵树一定是去掉最大的子树最优
#include <stdio.h> #include <iostream> #include <cstring> #include <algorithm> #include <cmath> #include <queue> #include <map> #include <stack> #include <sstream> #include <set> // #pragma GCC optimize(2) //#define int long long #define ls u<<1 #define rs u<<1|1 #define rep(i,a,n) for(int i=a;i<=n;i++) #define REP(i,a,n) for(int i=a;i>=n;--i) #define rush() int T;scanf("%d",&T);for(int Ti=1;Ti<=T;++Ti) #define IOS ios::sync_with_stdio(0); cin.tie(0); cout.tie(0); #define mm(i,v) memset(i,v,sizeof i); #define mp(a, b) make_pair(a, b) #define pi acos(-1) #define fi first #define se second using namespace std; typedef long long ll; typedef double db; typedef pair<ll, ll > PII; priority_queue< PII, vector<PII>, greater<PII> > que; stringstream ssin; // ssin << string while ( ssin >> int) const ll LINF = 0x7fffffffffffffffll; const int N = 4e5 + 5, M = 4e5 + 5, mod = 1e9 + 7, INF = 0x3f3f3f3f; int _, n, k, idx; int e[M], ne[M], h[N]; int flag, cnt; ll sum[N], a[N]; inline ll read() { char c=getchar();ll x=0,f=1; while(c<'0'||c>'9'){if(c=='-')f=-1; c=getchar();} while(c>='0'&&c<='9'){x=x*10+c-'0'; c=getchar();} return x*f; } void add(int a, int b) { e[idx] = b; ne[idx] = h[a]; h[a] = idx++; } void dfs(int u, int fa, ll mid) { sum[u] = a[u]; if (sum[u] > mid || flag) { flag = 1; return; } for (int i = h[u]; ~i; i = ne[i]) { int v = e[i]; if (v == fa) continue; dfs(v, u, mid); sum[u] += sum[v]; } if (sum[u] > mid) { vector<ll>vec; for (int i = h[u]; ~i; i = ne[i]) { int v = e[i]; if (v == fa) continue; vec.push_back(sum[v]); } sort(vec.begin(), vec.end()); for (int i = vec.size() - 1; i >= 0; --i) { if (sum[u] <= mid) break; sum[u] -= vec[i]; cnt++; } } if (cnt > k - 1) { flag = 1; } } bool ck(ll mid) { cnt = flag = 0; dfs(1, -1, mid); if (flag) return false; return true; } int main() { #ifndef ONLINE_JUDGE freopen("in.txt","r",stdin); freopen("out.txt","w",stdout); #endif _ = read(); ll cas = 0, ans; while (_--) { n = read(); k = read(); idx = 0; for (int i = 0; i <= n; ++i) h[i] = -1; rep(i, 1, n - 1) { int u, v; u = read(); v = read(); add(u, v); add(v, u); } rep(i, 1, n) a[i] = read(); ll l = 0ll, r = 1e14; while (l < r) { ll mid = l + r >> 1; if (ck(mid)) { r = mid; ans = mid; } else { l = mid + 1; } } printf("Case #%lld: %lld\n", ++cas, l); } // #ifndef ONLINE_JUDGE // system("pause"); // #endif }
D. Spanning Tree Removal
构造,对于每棵树 i,i + 1, i - 1, i + 2, i - 2, i + 3, i - 2......
#include <stdio.h> #include <iostream> #include <cstring> #include <algorithm> #include <cmath> #include <queue> #include <map> #include <stack> #include <sstream> #include <set> // #include <unordered_set> // #pragma GCC optimize(2) //#define int long long #define ls u<<1 #define rs u<<1|1 #define rep(i,a,n) for(int i=a;i<=n;i++) #define REP(i,a,n) for(int i=a;i>=n;--i) #define rush() int T;scanf("%d",&T);for(int Ti=1;Ti<=T;++Ti) #define IOS ios::sync_with_stdio(0); cin.tie(0); cout.tie(0); #define mm(i,v) memset(i,v,sizeof i); #define mp(a, b) make_pair(a, b) #define pi acos(-1) #define fi first #define se second using namespace std; typedef long long ll; typedef double db; typedef pair<ll, ll > PII; priority_queue< PII, vector<PII>, greater<PII> > que; stringstream ssin; // ssin << string while ( ssin >> int) const ll LINF = 0x7fffffffffffffffll; const int N = 1e3 + 5, M = 4e5 + 5, mod = 1e9 + 7, INF = 0x3f3f3f3f; int _, n; vector<PII>vec; bool vis[N]; inline ll read() { char c=getchar();ll x=0,f=1; while(c<'0'||c>'9'){if(c=='-')f=-1; c=getchar();} while(c>='0'&&c<='9'){x=x*10+c-'0'; c=getchar();} return x*f; } int main() { #ifndef ONLINE_JUDGE freopen("in.txt","r",stdin); freopen("out.txt","w",stdout); #endif int cas = 0; _ = read(); while (_--) { n = read(); printf("Case #%d: %d\n", ++cas, n / 2); rep(i, 1, n / 2) { int now = i - 1; printf("%d %d\n", now % n + 1, (now + 1) % n + 1); for (int j = 2; j <= n - 1; ++j) { if (j & 1) printf("%d %d\n", (now - j / 2 + n) % n + 1, (now + j / 2 + 1) % n + 1); else printf("%d %d\n", (now + j / 2) % n + 1, (now - j / 2 + n) % n + 1); } } } // #ifndef ONLINE_JUDGE // system("pause"); // #endif }