2017-2018 ACM-ICPC, Asia Tsukuba Regional Contest
思路:暴力枚举黑巧克力的个数和厚黑巧克力的个数
代码:
#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 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 LL C(int n, int m) { LL res = 1; if(n-m < m) m = n-m; for (int i = 1; i <= m; i++) { res *= (n-i+1); res /= i; } return res; } int main() { int l, k; LL res = 1; scanf("%d %d", &l, &k); LL ans = 0; for (int i = 1; i <= 51; i++) { for (int j = 0; j <= i; j++) { if(j*k + (i-j) + i-1 <= l) { ans += C(i, j); } } } printf("%lld ", 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 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 int a[10], b[10]; pii p[20]; pii delta[20]; int tmp[20][20]; piii T[500]; int t[500]; int vv[500]; int main() { int m; scanf("%d", &m); for (int i = 1; i <= m; i++) scanf("%d %d", &p[i].fi, &p[i].se); int cnt = 0; for (int i = 1; i <= m; i++) { for (int j = 1; j <= m; j++) { if(i == j) continue; int x = p[i].fi - p[j].fi; int y = p[i].se - p[j].se; int d = __gcd(x, y); x /= d; y /= d; if(x > 0 && y < 0) x = -x, y = -y; T[++cnt].fi.fi = x; T[cnt].fi.se = y; T[cnt].se = cnt; tmp[i][j] = cnt; } } sort(T+1, T+1+cnt); int now = 1; t[T[1].se] = now; for (int i = 2; i <= cnt; i++) { if(T[i].fi.fi == T[i-1].fi.fi && T[i].fi.se == T[i-1].fi.se) { t[T[i].se] = now; } else { t[T[i].se] = ++now; } } for (int i = 1; i <= m; i++) { for (int j = 1; j <= m; j++) { tmp[i][j] = t[tmp[i][j]]; } } int up = (1<<m)-1; int ans = 0; for (int i = 0; i <= up; i++) { if(__builtin_popcount(i) == m/2 && (up^i) < i) { int tot = 0, cnt = 0; for (int j = 0; j < m; j++) if((i&(1<<j)) == 0) a[++tot] = j+1; else b[++cnt] = j+1; do { int res = 0; for (int i = 1; i <= tot; i++) { res += vv[tmp[a[i]][b[i]]]; vv[tmp[a[i]][b[i]]]++; } for (int i = 1; i <= tot; i++) vv[tmp[a[i]][b[i]]]--; ans = max(ans, res); } while(next_permutation(a+1, a+1+tot)); // cout<<ans<<endl; } } printf("%d ", ans); return 0; }
思路:模拟
代码:
#include<bits/stdc++.h> using namespace std; typedef long long ll; const int maxn=1e5+5; ll a[maxn]; ll mol,den; int main() { ll n,t; scanf("%lld%lld",&n,&t); for(int i=0;i<n;i++) scanf("%lld",&a[i]); ll pre1=0,pre2=0; for(int i=0;i<n;i++) { // pre1+=a[i]; den=max(a[i],den); mol=t-pre1-a[i]>=0 ? t-pre1-a[i]:-den; pre1+=a[i]; printf("%lld ",mol/den+2); } }
D Making Perimeter of the Convex Hull Shortest
思路:先分别求出每个点到1和2的最短路d1[i], d2[i],
对于一条边u->v, 如果d1[v] + d2[u] + w < 1到2最短路径, 那么肯定是HAPPY
否则看这条边是不是1到2的所有最短路径所构成的无向图中的桥, 如果是桥, 删去后最短路肯定变大, 是SAD, 否则最短路径肯定不变, 是SOSO
代码:
#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 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 = 1e5 + 5; const LL INF = 0x3f3f3f3f3f3f3f3f; vector<pii> g[N], rg[N], tg[N]; int ans[N], u[N], v[N], w[N], low[N], dfn[N], tot = 0; pii fa[N]; LL d1[N], d2[N]; priority_queue<pli, vector<pli>, greater<pli> > q; void Dij1(int s) { mem(d1, INF); d1[s] = 0; q.push({0, s}); while(!q.empty()) { pli p = q.top(); q.pop(); int u = p.se; if(p.fi > d1[u]) continue; for (pii to : g[u]) { int v = to.fi; int w = to.se; if(d1[u] + w < d1[v]) { d1[v] = d1[u] + w; q.push({d1[v], v}); } } } } void Dij2(int s) { mem(d2, INF); d2[s] = 0; q.push({0, s}); while(!q.empty()) { pli p = q.top(); q.pop(); int u = p.se; if(p.fi > d2[u]) continue; for (pii to : rg[u]) { int v = to.fi; int w = to.se; if(d2[u] + w < d2[v]) { d2[v] = d2[u] + w; q.push({d2[v], v}); } } } } void tarjan(int u, pii o) { low[u] = dfn[u] = ++tot; fa[u] = o; for (pii p: tg[u]) { int v = p.fi; if(!dfn[v]) { tarjan(v, {u, p.se}); low[u] = min(low[u], low[v]); } else if(v != o.fi) low[u] = min(low[u], dfn[v]); } } int main() { int n, m; scanf("%d %d", &n, &m); for (int i = 1; i <= m; i++) { scanf("%d %d %d", &u[i], &v[i], &w[i]); g[u[i]].pb({v[i], w[i]}); rg[v[i]].pb({u[i], w[i]}); } Dij1(1); Dij2(2); for (int i = 1; i <= m; i++) { if(d1[v[i]] + w[i] + d2[u[i]] < d1[2]) ans[i] = 1; else if(d1[u[i]] + w[i] + d2[v[i]] == d1[2]) { tg[u[i]].pb({v[i], i}); tg[v[i]].pb({u[i], i}); } } tarjan(1, {1, 1}); for (int v = 2; v <= n; v++) { int u = fa[v].fi; int id = fa[v].se; if(low[v] > dfn[u]) ans[id] = 2; } for (int i = 1; i <= m; i++) { if(ans[i] == 1) puts("HAPPY"); else if(ans[i] == 2) puts("SAD"); else puts("SOSO"); } 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 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 char s[5]; int w, l; double f1(double x, double c) { return sqrt(3)*x + c; } double f2(double x, double c) { return -sqrt(3)*x + c; } int solve() { scanf("%s", s); scanf("%d %d", &w, &l); if(s[0] == 'B') w += 60; else if(s[0] == 'C') w += 120; double y = l * sin(w*pi/180.0); double x = - l * cos(w*pi/180.0); while(y > 2*sqrt(3)) y -= 2*sqrt(3); while(x > 2) x -= 2; while(x < 0) x += 2; if(0 <= x && x < 1) { if(0 <= y && y <= sqrt(3)) { if(y > f1(x, 0) && y > f2(x, sqrt(3))) return 4; else if(y < f1(x, 0) && y < f2(x, sqrt(3))) return 4; else if(y > f1(x, 0) && y < f2(x, sqrt(3))) { if(y > sqrt(3)/2.0) return 2; else return 1; } else { if(y > sqrt(3)/2.0) return 1; else return 2; } } else { if(y > f1(x, sqrt(3)) && y > f2(x, 2*sqrt(3))) return 3; else if(y < f1(x, sqrt(3)) && y < f2(x, 2*sqrt(3))) return 3; else if(y > f1(x, sqrt(3)) && y < f2(x, 2*sqrt(3))) { if(y > sqrt(3)*3.0/2.0) return 1; else return 2; } else { if(y > sqrt(3)*3.0/2.0) return 2; else return 1; } } } else { if(0 <= y && y <= sqrt(3)) { if(y > f1(x, -sqrt(3)) && y > f2(x, 2*sqrt(3))) return 3; else if(y < f1(x, -sqrt(3)) && y < f2(x, 2*sqrt(3))) return 3; else if(y > f1(x, -sqrt(3)) && y < f2(x, 2*sqrt(3))) { if(y > sqrt(3)/2.0) return 1; else return 2; } else { if(y > sqrt(3)/2.0) return 2; else return 1; } } else { if(y > f1(x, 0) && y > f2(x, 3*sqrt(3))) return 4; else if(y < f1(x, 0) && y < f2(x, 3*sqrt(3))) return 4; else if(y > f1(x, 0) && y < f2(x, 3*sqrt(3))) { if(y > sqrt(3)*3.0/2.0) return 2; else return 1; } else { if(y > sqrt(3)*3.0/2.0) return 1; else return 2; } } } } int main() { if(solve() == solve()) puts("YES"); else puts("NO"); return 0; }
H Homework
I Starting a Scenic Railroad Service
思路:
第一种就是求对于每个区间,有多少个区间与他相交, 取最大值, 这个用容斥做
第二种贪心求,每次从优先队列里取出右端点最靠前的,与当前区间左端点比较
#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 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 = 2e5 + 10, M = 1e5 + 10; pii a[N]; int n, bit[M], btt[M]; priority_queue<int, vector<int>, greater<int> > q; void add(int x, int ty) { if(ty == 1) { while(x < M) bit[x]++, x += x&-x; } else { while(x < M) btt[x]++, x += x&-x; } } int sum(int x, int ty) { int ans = 0; if(ty == 1) { while(x) ans += bit[x], x -= x&-x; } else { while(x) ans += btt[x], x -= x&-x; } return ans; } int main() { scanf("%d", &n); for (int i = 1; i <= n; i++) { scanf("%d %d", &a[i].fi, &a[i].se); } sort(a+1, a+1+n); for (int i = 1; i <= n; i++) { if(q.empty()) q.push(a[i].se); else { int p = q.top(); if(a[i].fi >= p) { q.pop(); q.push(a[i].se); } else q.push(a[i].se); } } int ans2 = q.size(), ans1 = 0; for (int i = 1; i <= n; i++) { add(a[i].se, 1); add(a[i].fi, 2); } for (int i = 1; i <= n; i++) { int t = n-1 - sum(a[i].fi, 1); t -= (n - sum(a[i].se-1, 2)); ans1 = max(ans1, t); // cout << a[i].fi << " " << a[i].se << " " << t << endl; } printf("%d %d ", ans1+1, ans2); return 0; }