2018 German Collegiate Programming Contest (GCPC 18)
Posted widsom
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了2018 German Collegiate Programming Contest (GCPC 18)相关的知识,希望对你有一定的参考价值。
2018 German Collegiate Programming Contest (GCPC 18)
建树,求lca
代码:
#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 << " "; #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 ‘ ‘ #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 = 1e9+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 = 1e3+9; string mp[maxn]; int anc[maxn*maxn][25]; int fa[maxn*maxn]; vector<int>tree[maxn*maxn]; int deep[maxn*maxn]; int vis[maxn][maxn]; int n,m; void bfs(int sx,int sy){ queue<pii>que; que.push(pii(sx,sy)); vis[sx][sy] = 1; while(!que.empty()){ int x = que.front().fi,y = que.front().se; que.pop(); int u = (x-1)*m + y; if(y<m && mp[x][2*y] != ‘|‘){ int tx = x,ty = y+1; if(vis[tx][ty] == 0){ vis[tx][ty] = 1; int v = (tx-1)*m+ty; que.push(pii(tx,ty)); tree[u].pb(v); tree[v].pb(u); } } if(y>1&&mp[x][2*y-2] != ‘|‘){ int tx = x,ty = y-1; if(vis[tx][ty] == 0){ vis[tx][ty] = 1; int v = (tx-1)*m+ty; que.push(pii(tx,ty)); tree[u].pb(v); tree[v].pb(u); } } if(x>1&&mp[x-1][2*y-1] != ‘_‘){ int tx = x-1,ty = y; if(vis[tx][ty] == 0){ vis[tx][ty] = 1; int v = (tx-1)*m+ty; que.push(pii(tx,ty)); tree[u].pb(v); tree[v].pb(u); } } if(x < n && mp[x][2*y-1] != ‘_‘){ int tx = x+1,ty = y; if(vis[tx][ty] == 0){ vis[tx][ty] = 1; int v = (tx-1)*m+ty; que.push(pii(tx,ty)); tree[u].pb(v); tree[v].pb(u); } } } } void dfs(int x){ anc[x][0] = fa[x]; for(int i=1; i<=22; i++){ anc[x][i] = anc[anc[x][i-1]][i-1]; } for(int i=0; i<tree[x].size(); i++){ if(tree[x][i]!=fa[x]){ int y = tree[x][i]; fa[y] = x; deep[y] = deep[x]+1; dfs(y); } } } int lca(int x,int y){ int dx = x,dy = y; if(deep[x] < deep[y]) swap(x,y); for(int i=22; i>=0; i--){ if(deep[y] <= deep[anc[x][i]]) x = anc[x][i]; } int rt; if(x==y)rt = x; else { for(int i=22; i>=0; i--){ if(anc[x][i] != anc[y][i]){ x = anc[x][i]; y = anc[y][i]; } } rt = anc[x][0]; } return deep[dx]+deep[dy] -2* deep[rt]; } int main(){ //scanf("%d%d", &n, &m); cin>>n>>m; getline(cin,mp[0]); for(int i=0; i<=n; i++) getline(cin, mp[i]); bfs(1,1); dfs(1); int q,la; ll ans = 0; scanf("%d", &q); for(int i=1; i<=q; i++){ int x,y; scanf("%d%d", &x, &y); if(i==1) la = (x-1)*m + y; else { int now = (x-1)*m + y; ans += 1ll*lca(la, now); //debug(lca(la,now)); la = now; } } printf("%I64d ", ans); return 0; }
求两点不经过圆内的最短路径
代码:
#include<bits/stdc++.h> using namespace std; #define pi acos(-1.0) double dis(double x1, double y1, double x2, double y2) { return sqrt((x1-x2)*(x1-x2) + (y1-y2)*(y1-y2)); } int main() { double x1, x2, y1, y2, ox, oy, r; scanf("%lf %lf", &x1, &y1); scanf("%lf %lf", &x2, &y2); scanf("%lf %lf %lf", &ox, &oy, &r); scanf("%lf %lf %lf", &ox, &oy, &r); double c = dis(x1, y1, x2, y2); double a = dis(ox, oy, x1, y1); double b = dis(ox, oy, x2, y2); double alpha = acos((a*a + c*c - b*b) / (2*a*c)); double beta = acos((b*b + c*c - a*a) / (2*b*c)); if(alpha > pi/2 || beta > pi/2) { printf("%.10f ", c); return 0; } alpha = acos((a*a +b*b - c*c)/ (2*a*b)); double d = a*b*sin(alpha)/c; if(d < r) { double aa = acos(r/a); double bb = acos(r/b); alpha -= aa; alpha -= bb; printf("%.10f ", sqrt(a*a - r*r) + sqrt(b*b - r*r) + alpha*r); } else printf("%.10f ", c); return 0; }
按拓扑序转移
代码:
//#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 << " "; #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 ‘ ‘ #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 = 1e9+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 = 1e3+9; vector<pii>mp[maxn]; queue<int>p,que; int n,m; int in[maxn]; int dp[maxn]; void topo(){ for(int i=1; i<=n; i++){ if(in[i] == 0)p.push(i); } while(!p.empty()){ int u = p.front();p.pop(); que.push(u); for(int i=0; i<mp[u].size(); i++){ int v = mp[u][i].fi; in[v]--; if(in[v] == 0) p.push(v); } } } int main(){ scanf("%d%d", &n, &m); for(int i=1; i<=m; i++) { int u,v,w; scanf("%d%d%d", &u, &v, &w); mp[u].pb(pii(v,w)); in[v]++; } topo(); int mx = 0; while(!que.empty()){ int u = que.front(); que.pop(); for(int i=0; i<mp[u].size(); i++){ int v = mp[u][i].fi,c = mp[u][i].se; dp[v] = max(dp[v], dp[u] + c); mx = max(mx, dp[v]); } } printf("%d ", mx); return 0; }
求区间交集
代码:
#include<bits/stdc++.h> #define pb push_back #define int long long using namespace std; const int maxn=3e5+10; const int mod=1e9+10+7; int32_t main() { int n; cin>>n; int ans=1e9+10; int l=0; int r=1e9+10; for(int i=1;i<=n;i++) { int x; cin>>x; if(l>x) { cout<<0<<endl; return 0; } int q=x-r; int p=x-l; if(p>x) p=x; if(q<0) q=0; //cout<<q<<" "<<p<<endl; l=q; r=p; ans=min(ans,r-l+1); } cout<<ans<<endl; }
乘1e5再算
代码:
//#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 << " "; #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 ‘ ‘ #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 = 1e9+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 = 1e5; int gcd(int a, int b){ if(b == 0)return a; return gcd(b, a % b); } bool check(int x){ if(x == 1) return false; for(int i=2; i*i <= x; i++){ if(x % i==0)return false; } return true; } int main(){ // cout<<gcd(5 ,10)<<endl; int T; scanf("%d", &T); double a,b; int n,m; while(T--){ scanf("%lf%lf", &a, &b); a += 5e-6; b += 5e-6; n = (int)(a * maxn ); m = (int)(b * maxn); //cout<<n<<" "<<m<<endl; int q = __gcd(n, m); n = n/q; m = m/q; // cout<<n<<" "<<m<<endl; if(n == m) printf("2 2 "); else if(check(n) && check(m)){ printf("%d %d ", n,m); } else puts("impossible"); } return 0; }
代码:
#include<bits/stdc++.h> #define pb push_back #define int long long using namespace std; const int maxn=1e6+10; const int mod=1e9+7; vector<int> vs[maxn]; int32_t main() { int n; cin>>n; for(int i=1;i<=n;i++) { int x; cin>>x; vs[x].push_back(i); } int l=1; int r=1; if(vs[1].size()>=2) { cout<<vs[1][0]<<" "<<vs[1][1]<<endl; return 0; } while(1) { if(l>1e6||r>1e6) { break; } int k=l+r; l=r; r=k; //cout<<l<<" "<<r<<endl; if(vs[l].size()&&vs[r].size()) { cout<<vs[l][0]<<" "<<vs[r][0]<<endl; return 0; } } cout<<"impossible"<<endl; }
1^(n-1) + 2^(n-1) + ... + s^(n-1) = m
代码:
#include<bits/stdc++.h> #define pb push_back #define int long long using namespace std; const int maxn=1e6+10; const int mod=1e9+7; vector<int> vs[maxn]; int32_t main() { int n; cin>>n; for(int i=1;i<=1e6;i++) { int x=i*(i+1)*(2*i+1)/6; if(x<n) { continue; } if(n==x) { cout<<3<<" "<<i<<endl; return 0; } if(x>n) { break; } } for(int p=4;p<=64;p++) { int ans=0; for(int i=1;i<=1e6;i++) { int t=1; for(int c=1;c<p;c++) { t*=i; } ans+=t; if(ans<n) continue; else if(ans==n) { cout<<p<<" "<<i<<endl; return 0; } else { break; } } } cout<<"impossible"<<endl; }
代码:
//#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 << " "; #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 ‘ ‘ #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 = 1e9+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 = 1e3+9; int h[maxn],v[maxn],dif[maxn]; int n; bool check(int x){ for(int i=1; i<=n; i++){ if(dif[i] + x > 0) return true; else if(dif[i] + x < 0)return false; } return true; } int main(){ scanf("%d", &n); for(int i=1; i<=n; i++) scanf("%d", &h[i]); for(int i=1; i<=n; i++) scanf("%d", &v[i]); for(int i=1; i<=n; i++) dif[i] = h[i] - v[i]; int ans = 0; for(int i=0; i<=maxn; i++){ if(check(i)){ans = i;break;} } printf("%d ", ans); return 0; }
模拟
代码:
#pragma GCC optimize(2) #pragma GCC optimize(3) #pragma GCC optimize(4) #include<bits/stdc++.h> using namespace std; #define fi first #define se second #define pi acos(-1.0) #define LL long long //#define mp make_pair #define pb push_back #define ls rt<<1, l, m #define rs rt<<1|1, m+1, r #define ULL unsigned LL #define pll pair<LL, LL> #define pli pair<LL, int> #define pii pair<int, int> #define piii pair<pii, int> #define pdd pair<long double, long double> #define mem(a, b) memset(a, b, sizeof(a)) #define fio ios::sync_with_stdio(false);cin.tie(0);cout.tie(0); #define fopen freopen("in.txt", "r", stdin);freopen("out.txt", "w", stout); //head const int N = 3e5 + 10; int a[N][4]; int t[N*2][2]; vector<int> vc; int main() { int n; scanf("%d", &n); int st = -1; int tmp[4]; for (int i = 1; i <= n; i++) { for (int j = 0; j < 4; j++) { scanf("%d", &a[i][j]); if(a[i][j]) { int tmp = a[i][j]; if(t[tmp][0]) t[tmp][1] = i; else t[tmp][0] = i; } } swap(a[i][0], a[i][2]); for (int j = 0; j < 4; j++) { if(!a[i][j] && !a[i][(j+1)%4]) st = i; } } for (int j = 0; j < 4; j++) { if(!a[st][j] && !a[st][(j+1)%4]) { tmp[0] = tmp[1] = 0; tmp[2] = a[st][(j+2)%4]; tmp[3] = a[st][(j+3)%4]; break; } } if(~st); else return 0*puts("impossible"); vc.pb(st); for (int j = 0; j < 4; j++) a[st][j] = tmp[j]; while(true) { int now = vc.back(); if(!a[now][2]) break; int id = a[now][2]; int nx; if(t[id][0] == now) nx = t[id][1]; else nx = t[id][0]; for (int j = 0; j < 4; j++) { if(a[nx][j] == id) { tmp[0] = a[nx][j]; tmp[1] = a[nx][(j+1)%4]; tmp[2] = a[nx][(j+2)%4]; tmp[3] = a[nx][(j+3)%4]; break; } } for (int j = 0; j < 4; j++) a[nx][j] = tmp[j]; if(a[nx][1]) return 0*puts("impossible"); vc.pb(nx); } int m = (int)vc.size(); if(n%m) return 0*puts("impossible"); if(n == m) { for (int i = 0; i < n; i++) if(a[vc[i]][3]) return 0*puts("impossible"); } for (int i = m; i < n; i++) { int now = vc[i-m]; if(!a[now][3]) return 0*puts("impossible"); int id= a[now][3]; int nx; if(t[id][0] == now) nx = t[id][1]; else nx = t[id][0]; for (int j = 0; j < 4; j++) { if(a[nx][j] == id) { tmp[1] = a[nx][j]; tmp[2] = a[nx][(j+1)%4]; tmp[3] = a[nx][(j+2)%4]; tmp[0] = a[nx][(j+3)%4]; break; } } for (int j = 0; j < 4; j++) a[nx][j] = tmp[j]; if(i%m == 0 && a[nx][0]) return 0*puts("impossible"); if(i%m == m-1 && a[nx][2]) return 0*puts("impossible"); if(i%m > 0 && (a[nx][0] != a[vc[i-1]][2] || a[nx][0] == 0)) return 0*puts("impossible"); if(i >= n-m && a[nx][3]) return 0*puts("impossible"); if(i < n-m && a[nx][3] == 0) return 0*puts("impossible"); vc.pb(nx); } printf("%d %d", n/m, m); for (int i = 0; i < n; i++) { if(i%m == 0) printf(" "); printf("%d ", vc[i]); } return 0; }
dp[i][j]:和为i且线段个数为j是否存在
代码:
#pragma GCC optimize(2) #pragma GCC optimize(3) #pragma GCC optimize(4) #include<bits/stdc++.h> using namespace std; #define fi first #define se second #define pi acos(-1.0) #define LL long long //#define mp make_pair #define pb push_back #define ls rt<<1, l, m #define rs rt<<1|1, m+1, r #define ULL unsigned LL #define pll pair<LL, LL> #define pli pair<LL, int> #define pii pair<int, int> #define piii pair<pii, int> #define pdd pair<long double, long double> #define mem(a, b) memset(a, b, sizeof(a)) #define fio ios::sync_with_stdio(false);cin.tie(0);cout.tie(0); #define fopen freopen("in.txt", "r", stdin);freopen("out.txt", "w", stout); //head const int N = 66, M = 2e3 + 5; const int INF = 0x3f3f3f3f; const double eps = 5e-6; int a[N], n, g; bool dp[M][N]; int main() { scanf("%d %d", &n, &g); for (int i = 1; i <= n; i++) scanf("%d", &a[i]); dp[0][0] = true; for (int i = 1; i <= n; i++) { for (int j = M-1; j >= a[i]; j--) { for (int k = n; k >= 1; k--) { dp[j][k] |= dp[j-a[i]][k-1]; } } } double ans = -1; for (int j = g-10; j < M; j++) { for (int i = 1; i <= n; i++) { if(dp[j][i]) { if(j+10-g <= 5*(i+1)) ans = max((j+10.0-g)/(double)(i+1), ans); } } } if(ans < -0.5) printf("impossible"); else printf("%.9f ", ans); return 0; }
模拟:
代码:
#include<bits/stdc++.h> using namespace std; #define pb push_back const int N = 110; int a[N][N]; int h, w; bool vis[N][N]; int dir[4][2] = {0, 1, 1, 0, 0, -1, -1, 0}; int main() { scanf("%d %d", &h, &w); for (int i = 0; i <= h+1; i++) { for (int j = 0; j <= w+1; j++) { scanf("%d", &a[i][j]); } } bool f = false; for (int i = 0; i <= h+1; i++) { for (int j = 0; j <= w+1; j++) { int cnt = 0; for (int ii = -1; ii <= 1; ii++) { for (int jj = -1; jj <= 1; jj++) { int x = i + ii; int y = j + jj; if(1 <= x && x <= h && 1 <= y && y <= w) { if(vis[x][y]) cnt++; } } } int res = a[i][j] - cnt; int x = i+1, y = j+1; if(1 <= x && x <= h && 1 <= y && y <= w) { if(res < 0 || res > 1) { f = true; break; } else if(res == 1){ vis[x][y] = true; } } else { if(res != 0) { f = true; break; } } } } if(f) puts("impossible"); else { for (int i = 1; i <= h; i++) { for (int j = 1; j <= w; j++){ if(vis[i][j]) putchar(‘X‘); else putchar(‘.‘); } puts(""); } } return 0; }
按高度从小到大启发式合并并查集,合并并查集时更新答案为当前高度
代码:
#include<bits/stdc++.h> using namespace std; #define fi first #define se second #define pi acos(-1.0) #define y1 y11 #define pb push_back #define pii pair<int, int> const int N = 505, M = 1e6 + 10, MM = 1e5 + 10, NN = N*N; int fa[NN], sz[NN]; int h[N][N], n, m; vector<pii> vc[M]; int x1[MM], y1[MM], x2[MM], y2[MM], ans[MM]; set<int> s[NN], que[NN]; map<int, int> mp[NN]; int dir[4][2] = {1, 0, 0, 1, -1, 0, 0, -1}; void init() { for (int i = 0; i < N*N; i++) fa[i] = i, s[i].insert(i); } int get_id(int x, int y) { return (x-1)*n + y; } int Find(int x) { if(x == fa[x]) return x; else return fa[x] = Find(fa[x]); } void Merge(int x, int y, int h) { x = Find(x); y = Find(y); if(x == y) return ; if(s[x].size() < s[y].size()) { fa[x] = y; for(int a : s[x]) { s[y].insert(a); for (int b : que[a]) { if(s[y].find(b) != s[y].end() && mp[a].find(b) == mp[a].end()) { mp[a][b] = h; mp[b][a] = h; } } } } else { fa[y] = x; for(int a : s[y]) { s[x].insert(a); for (int b : que[a]) { if(s[x].find(b) != s[x].end() && mp[a].find(b) == mp[a].end()) { mp[a][b] = h; mp[b][a] = h; } } } } } void solve() { for (int i = 1; i < M; i++) { for (pii p : vc[i]) { int x = p.fi; int y = p.se; int id = get_id(x, y); for (int j = 0; j < 4; j++) { int xx = x + dir[j][0]; int yy = y + dir[j][1]; if(xx < 1 || xx > m || yy < 1 || yy > n) continue; if(h[xx][yy] <= i) { Merge(id, get_id(xx, yy), i); } } } } } int main() { int q; scanf("%d %d %d", &m, &n, &q); for (int i = 1; i <= m; i++) { for (int j = 1; j <= n; j++) { scanf("%d", &h[i][j]); vc[h[i][j]].pb({i, j}); } } for (int i = 1; i <= q; i++) { scanf("%d %d %d %d", &x1[i], &y1[i], &x2[i], &y2[i]); if(x1[i] == x2[i] && y1[i] == y2[i]) { ans[i] = h[x1[i]][y1[i]]; } else { int id1 = get_id(x1[i], y1[i]); int id2 = get_id(x2[i], y2[i]); que[id1].insert(id2); que[id2].insert(id1); } } init(); solve(); for (int i = 1; i <= q; i++) { if(ans[i]) printf("%d ", ans[i]); else printf("%d ", mp[get_id(x1[i], y1[i])][get_id(x2[i], y2[i])]); } return 0; }
以上是关于2018 German Collegiate Programming Contest (GCPC 18)的主要内容,如果未能解决你的问题,请参考以下文章
(寒假GYM开黑)2018 German Collegiate Programming Contest (GCPC 18)
(寒假开黑gym)2017-2018 ACM-ICPC German Collegiate Programming Contest (GCPC 2017)
German Collegiate Programming Contest 2018? A. Attack on Alpha-Zet
ACM International Collegiate Programming Contest, Tishreen Collegiate Programming Contest (2018) Syr
ACM International Collegiate Programming Contest, JUST Collegiate Programming Contest (2018)