2017-2018 ACM-ICPC, Asia Tsukuba Regional Contest

2017-2018 ACM-ICPC, Asia Tsukuba Regional Contest

Secret of Chocolate Poles

思路:暴力枚举黑巧克力的个数和厚黑巧克力的个数

代码:

#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\n", ans);
    return 0;
}
View Code

 

Parallel Lines

思路:预处理+暴力

代码:

#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\n", ans);
    return 0;
}
View Code

 

Medical Checkup

思路:模拟

代码:

#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\n",mol/den+2);
    }
}
View Code

 

Making Perimeter of the Convex Hull Shortest

Black or White

Pizza Delivery

思路:先分别求出每个点到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;
}
View Code

 

Rendezvous on a Tetrahedron

思路:将立体问题转换成平面问题

代码:

#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;
}
View Code

 

Homework

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\n", ans1+1, ans2);
    return 0;
}
View Code

 

String Puzzle

Counting Cycles

转载于:https://www.cnblogs.com/widsom/p/10008098.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值