湖南2020多校对抗赛round3 CERC2014
题号 赛中 赛后
Parades    
Mountainous landscape    
Sums  
Wheels  
Can't stop playing    
Vocabulary  
Virus synthesis    
Good morning!  
Bricks  
Pork barrel    
The Imp    
Outer space invaders  

 

 

这场真是模拟贪心完后就一直dp

人给dp傻了

人给wa傻了

cwolf9牛逼

A.Parades

比较牛逼的树形dp吧,待补

题意:给你一个树,有q个询问,每个询问会占用\(u_i->v_i\)的路径,求最多可以取多少个询问,使得这些询问之间的路径不重合

C.Sums

题意:求一个数是否 是一段连续数字的和,使得最大的那个数字尽可能小

简单推一下就行

\(假设有x项连续的数组成n\)

\(则(a+1)+(a+2)+...+(a+x)=n\)

\(根据等差数列公式可得\)

\(\frac {(a+1+a+x)*x}{2}=n\)

\(a*x+\frac{(1+x)*x}{2}=n\)

\(n-\frac{(1+x)*x}{2}=a*x\)

所以得出这个同余关系就可以直接扫一遍即可

代码如下

#include <set>
#include <map>
#include <stack>
#include <cmath>
#include <queue>
#include <cstdio>
#include <string>
#include <bitset>
#include <vector>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
typedef long long LL;
typedef pair<int, int> pii;
typedef unsigned long long uLL;
#define ls rt<<1
#define rs rt<<1|1
#define lson l,mid,rt<<1
#define rson mid+1,r,rt<<1|1
#define bug printf("*********\n")
#define FIN freopen("input.txt","r",stdin);
#define FON freopen("output.txt","w+",stdout);
#define IO ios::sync_with_stdio(false),cin.tie(0)
#define debug1(x) cout<<"["<<#x<<" "<<(x)<<"]\n"
#define debug2(x,y) cout<<"["<<#x<<" "<<(x)<<" "<<#y<<" "<<(y)<<"]\n"
#define debug3(x,y,z) cout<<"["<<#x<<" "<<(x)<<" "<<#y<<" "<<(y)<<" "<<#z<<" "<<z<<"]\n"
const int maxn = 3e5 + 5;
const int INF = 0x3f3f3f3f;
const int mod = 1e9 + 7;
const double Pi = acos(-1);
LL gcd(LL a, LL b) {
    return b ? gcd(b, a % b) : a;
}
LL lcm(LL a, LL b) {
    return a / gcd(a, b) * b;
}
double dpow(double a, LL b) {
    double ans = 1.0;
    while(b) {
        if(b % 2)ans = ans * a;
        a = a * a;
        b /= 2;
    } return ans;
}
LL quick_pow(LL x, LL y) {
    LL ans = 1;
    while(y) {
        if(y & 1) {
            ans = ans * x % mod;
        } x = x * x % mod;
        y >>= 1;
    } return ans;
}
LL sum[maxn];
int main() {
#ifndef ONLINE_JUDGE
    FIN
#endif
    for(LL i = 1; i <= 1e5; i++) {
        sum[i] = i * (i - 1) / 2LL;
    }
    for(int i=1;i<=10;i++){
        debug1(sum[i]);
    }
    int T;
    scanf("%d", &T);
    while(T--) {
        LL n;
        scanf("%lld", &n);
        int flag = 0;
        for(LL i = 2; i < 1e5&&!flag; i++) {
            debug2(n,sum[i]);
            if(sum[i] < n && (n - sum[i]) % i == 0) {
                printf("%lld = ", n);
                int pos = (n - sum[i]) / i;
                debug1(pos);
                for(LL j = 0; j < i; j++) {
                    if(j) {
                        printf(" + ");
                    }
                    printf("%lld", pos + j);
                }
                printf("\n");
                flag = 1;
            }
        }
        if(!flag) {
            printf("IMPOSSIBLE\n");
        }
    }
    return 0;
}

D.Wheels

题意:给你n个轮子,第一个轮子是顺时针按照角速度为1 来旋转的,问,n个轮子的旋转状态

模拟一下即可,判断轮子是否相切,角速度之比等于轮子半径的反比

#include <set>
#include <map>
#include <stack>
#include <cmath>
#include <queue>
#include <cstdio>
#include <string>
#include <bitset>
#include <vector>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
typedef long long LL;
typedef pair<int, int> pii;
typedef unsigned long long uLL;
#define ls rt<<1
#define rs rt<<1|1
#define lson l,mid,rt<<1
#define rson mid+1,r,rt<<1|1
#define bug printf("*********\n")
#define FIN freopen("input.txt","r",stdin);
#define FON freopen("output.txt","w+",stdout);
#define IO ios::sync_with_stdio(false),cin.tie(0)
#define debug1(x) cout<<"["<<#x<<" "<<(x)<<"]\n"
#define debug2(x,y) cout<<"["<<#x<<" "<<(x)<<" "<<#y<<" "<<(y)<<"]\n"
#define debug3(x,y,z) cout<<"["<<#x<<" "<<(x)<<" "<<#y<<" "<<(y)<<" "<<#z<<" "<<z<<"]\n"
const int maxn = 3e5 + 5;
const int INF = 0x3f3f3f3f;
const int mod = 1e9 + 7;
const double Pi = acos(-1);
LL gcd(LL a, LL b) {
    return b ? gcd(b, a % b) : a;
}
LL lcm(LL a, LL b) {
    return a / gcd(a, b) * b;
}
double dpow(double a, LL b) {
    double ans = 1.0;
    while(b) {
        if(b % 2)ans = ans * a;
        a = a * a;
        b /= 2;
    } return ans;
}
LL quick_pow(LL x, LL y) {
    LL ans = 1;
    while(y) {
        if(y & 1) {
            ans = ans * x % mod;
        } x = x * x % mod;
        y >>= 1;
    } return ans;
}

struct Point {
    int x, y;
    LL r;
    pair<LL, LL> ans;
    int flag;
} a[maxn];
int vis[maxn];
LL get(Point a, Point b) {
    return 1LL * (a.x - b.x) * (a.x - b.x) + 1LL * (a.y - b.y) * (a.y - b.y);
}
bool check(Point a, Point b) {
    LL disab = get(a, b);
    LL disrr = 1LL * (a.r + b.r) * (a.r + b.r);
    return disab == disrr;
}
int main() {
#ifndef ONLINE_JUDGE
    FIN
#endif
    int T;
    scanf("%d", &T);
    while(T--) {
        int n;
        scanf("%d", &n);
        for(int i = 1; i <= n; i++) {
            vis[i] = 0;
            a[i].flag = -1;
            a[i].ans = make_pair(1, 1);
            scanf("%d%d%lld", &a[i].x, &a[i].y, &a[i].r);
        }
        a[1].ans = make_pair(1, 1);
        a[1].flag = 1;
        queue<int> q;
        while(!q.empty()) {
            q.pop();
        }
        q.push(1);
        while(!q.empty()) {
            int now = q.front();
            q.pop();
            if(vis[now]) continue;
            vis[now] = 1;
            for(int i = 1; i <= n; i++) {
                if(vis[i]) continue;
                if(check(a[i], a[now])) {
                    a[i].flag = !a[now].flag;
                    a[i].ans = make_pair(a[now].ans.first * a[now].r, a[now].ans.second * a[i].r);
                    int d = gcd(a[i].ans.first, a[i].ans.second);
                    a[i].ans.first /= d;
                    a[i].ans.second /= d;
                    q.push(i);
                }
            }
        }

        for(int i = 1; i <= n; i++) {
            if(!vis[i]) {
                printf("not moving\n");
            } else {
                if(a[i].ans.first == 1 && a[i].ans.second == 1) {
                    printf("1 ");
                } else {
                    if(a[i].ans.second == 1) {
                        printf("%lld ", a[i].ans.first);
                    } else {
                        printf("%lld/%lld ", a[i].ans.first, a[i].ans.second);
                    }
                }
                if(a[i].flag) {
                    printf("clockwise\n");
                } else {
                    printf("counterclockwise\n");
                }
            }
        }
    }
    return 0;
}

F.Vocabulary

cwolf9绝杀出来的,待补

H.Good morning!

题意:模拟键盘输入,只能从当前按键往左下按,每个按键可以按任意多次,求可以按出来的离给出的数字最近的数是哪个

因为n特别小,所以枚举差值更新答案是否可达即可

#include <set>
#include <map>
#include <stack>
#include <cmath>
#include <queue>
#include <cstdio>
#include <string>
#include <bitset>
#include <vector>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
typedef long long LL;
typedef pair<int, int> pii;
typedef unsigned long long uLL;
#define ls rt<<1
#define rs rt<<1|1
#define lson l,mid,rt<<1
#define rson mid+1,r,rt<<1|1
#define bug printf("*********\n")
#define FIN freopen("input.txt","r",stdin);
#define FON freopen("output.txt","w+",stdout);
#define IO ios::sync_with_stdio(false),cin.tie(0)
#define debug1(x) cout<<"["<<#x<<" "<<(x)<<"]\n"
#define debug2(x,y) cout<<"["<<#x<<" "<<(x)<<" "<<#y<<" "<<(y)<<"]\n"
#define debug3(x,y,z) cout<<"["<<#x<<" "<<(x)<<" "<<#y<<" "<<(y)<<" "<<#z<<" "<<z<<"]\n"
const int maxn = 3e5 + 5;
const int INF = 0x3f3f3f3f;
const int mod = 1e9 + 7;
const double Pi = acos(-1);
LL gcd(LL a, LL b) {
    return b ? gcd(b, a % b) : a;
}
LL lcm(LL a, LL b) {
    return a / gcd(a, b) * b;
}
double dpow(double a, LL b) {
    double ans = 1.0;
    while(b) {
        if(b % 2)ans = ans * a;
        a = a * a;
        b /= 2;
    } return ans;
}
LL quick_pow(LL x, LL y) {
    LL ans = 1;
    while(y) {
        if(y & 1) {
            ans = ans * x % mod;
        } x = x * x % mod;
        y >>= 1;
    } return ans;
}
bool check(int val) {
    vector<int>vec;
    while(val) {
        vec.push_back(val % 10);
        val /= 10;
    }
    reverse(vec.begin(), vec.end());
    int pos = vec[0];
    bool flag = true;
    int sz = vec.size();
    for(int i = 1; i < sz && flag; i++) {
        if(vec[i] == pos) {
            continue;
        }
        if(vec[i] != 0) {
            if(vec[i] < pos) {
                flag = 0;
            } else {
                if(pos == 1 || pos == 4 || pos == 7) {
                    pos = vec[i];
                } else {
                    if(pos == 2) {
                        if(vec[i] == 4 || vec[i] == 7) {
                            flag = 0;
                        }
                    }
                    if(pos == 5) {
                        if(vec[i] == 7) {
                            flag = 0;
                        }
                    }
                    if(pos == 3) {
                        if(vec[i] == 3 || vec[i] == 6 || vec[i] == 9) {
                            pos = vec[i];
                        } else {
                            flag = 0;
                        }
                    }
                    if(pos == 6) {
                        if(vec[i] == 6 || vec[i] == 9) {
                            pos = vec[i];
                        } else {
                            flag = 0;
                        }
                    }
                    if(pos == 9) {
                        if(vec[i] == 9) {
                            pos = vec[i];
                        } else {
                            flag = 0;
                        }
                    }
                    if(pos == 0) {
                        if(vec[i] != 0) {
                            flag = 0;
                        }
                    }
                    pos = vec[i];
                }
            }
        } else {
            if(pos == 1 || pos == 4 || pos == 7 || pos == 2 || pos == 5 || pos == 8 || pos == 0) {
                pos = vec[i];
            } else {
                flag = 0;
            }
        }
    }
    return flag;
}
int main() {
#ifndef ONLINE_JUDGE
    FIN
#endif
    int T;
    scanf("%d", &T);
    while(T--) {
        int k;
        scanf("%d", &k);
        for(int i = 0; i <= 1000; i++) {
            int Max = k + i;
            int Min = max(0, k - i);
            if(check(Max)) {
                printf("%d\n", Max);
                break;
            }

            if(check(Min)) {
                printf("%d\n", Min);
                break;
            }
        }
    }
    return 0;
}

I.Bricks

题意:给你一些联系的B和W,问你最多可以分割多少块,使得每一块当中B和W的比例是相同的

题解:比例是固定的,b的总数比上w的总数,这个比较好推,假设第一块中b的数量为a1,w的数量为b1

第二块中b的数量为a2,w的数量为b2

那么a1:b1=a2:b2,那么a1+a2:b1+b2=a1:b1

知道了比例后,就从前往后尽可能的使得数量尽可能少的比过去

#include <set>
#include <map>
#include <stack>
#include <cmath>
#include <queue>
#include <cstdio>
#include <string>
#include <bitset>
#include <vector>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
typedef long long LL;
typedef pair<int, int> pii;
typedef unsigned long long uLL;
#define ls rt<<1
#define rs rt<<1|1
#define lson l,mid,rt<<1
#define rson mid+1,r,rt<<1|1
#define bug printf("*********\n")
#define FIN freopen("input.txt","r",stdin);
#define FON freopen("output.txt","w+",stdout);
#define IO ios::sync_with_stdio(false),cin.tie(0)
#define debug1(x) cout<<"["<<#x<<" "<<(x)<<"]\n"
#define debug2(x,y) cout<<"["<<#x<<" "<<(x)<<" "<<#y<<" "<<(y)<<"]\n"
#define debug3(x,y,z) cout<<"["<<#x<<" "<<(x)<<" "<<#y<<" "<<(y)<<" "<<#z<<" "<<z<<"]\n"
const int maxn = 3e5 + 5;
const int INF = 0x3f3f3f3f;
const int mod = 1e9 + 7;
const double Pi = acos(-1);
LL gcd(LL a, LL b) {
    return b ? gcd(b, a % b) : a;
}
LL lcm(LL a, LL b) {
    return a / gcd(a, b) * b;
}
double dpow(double a, LL b) {
    double ans = 1.0;
    while(b) {
        if(b % 2)ans = ans * a;
        a = a * a;
        b /= 2;
    } return ans;
}
LL quick_pow(LL x, LL y) {
    LL ans = 1;
    while(y) {
        if(y & 1) {
            ans = ans * x % mod;
        } x = x * x % mod;
        y >>= 1;
    } return ans;
}
int num[maxn];
int flag[maxn];
char str[5];
LL d[3];
LL sum[3];
int main() {
#ifndef ONLINE_JUDGE
    FIN
#endif
    int T;
    scanf("%d", &T);
    while(T--) {
        int n;
        scanf("%d", &n);
        sum[0] = sum[1] = 0;
        d[0] = d[1] = 0;
        for(int i = 1; i <= n; i++) {
            scanf("%d%s", &num[i], str);
            if(str[0] == 'B') {
                sum[0] += num[i];
                flag[i] = 0;
            } else {
                sum[1] += num[i];
                flag[i] = 1;
            }
        }
        if(sum[0] == 0 || sum[1] == 0) {
            printf("%d\n", sum[0] + sum[1]);
            continue;
        }
        int ans = 0;
        for(int i = 1; i <= n; i++) {
            LL x = sum[flag[i]] * d[flag[i] ^ 1] - d[flag[i]] * sum[flag[i] ^ 1];
            if(x % sum[flag[i] ^ 1] || x <= 0 || x / sum[flag[i] ^ 1] > num[i]) {
                d[flag[i]] += num[i];
            } else {
                ans++;
                d[flag[i]] = num[i] - x / sum[flag[i] ^ 1];
                d[flag[i] ^ 1] = 0;
            }
        }
        printf("%d\n", ans);
    }
    return 0;
}

L.Outer space invaders

题意,有n个外星人,外星人存在的时间是L[i],R[i],你要在外星人存在的时间内消灭外星人,外星人距离你为d[i],消灭距离为d[i]的外星人所需要花费的最小代价为d[i]

问消灭所有外星人所花费的最小代价

题解

将外星人存在的时间离散化后dp

\(dp_{ij}表示消灭时间在i-j之间的所有外星人所需要花费的最小代价为多少,那么一定是该时间段内d[i]的最大值,然后枚举时间点转移即可\)

\(dp_{ij}=min(dp[i][k-1]+dp[k+1][j]+d[k])\)

#include <set>
#include <map>
#include <stack>
#include <cmath>
#include <queue>
#include <cstdio>
#include <string>
#include <bitset>
#include <vector>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
typedef long long LL;
typedef pair<int, int> pii;
typedef unsigned long long uLL;
#define ls rt<<1
#define rs rt<<1|1
#define lson l,mid,rt<<1
#define rson mid+1,r,rt<<1|1
#define bug printf("*********\n")
#define FIN freopen("input.txt","r",stdin);
#define FON freopen("output.txt","w+",stdout);
#define IO ios::sync_with_stdio(false),cin.tie(0)
#define debug1(x) cout<<"["<<#x<<" "<<(x)<<"]\n"
#define debug2(x,y) cout<<"["<<#x<<" "<<(x)<<" "<<#y<<" "<<(y)<<"]\n"
#define debug3(x,y,z) cout<<"["<<#x<<" "<<(x)<<" "<<#y<<" "<<(y)<<" "<<#z<<" "<<z<<"]\n"
const int maxn = 3e5 + 5;
const int INF = 0x3f3f3f3f;
const int mod = 1e9 + 7;
const double Pi = acos(-1);
LL gcd(LL a, LL b) {
    return b ? gcd(b, a % b) : a;
}
LL lcm(LL a, LL b) {
    return a / gcd(a, b) * b;
}
double dpow(double a, LL b) {
    double ans = 1.0;
    while(b) {
        if(b % 2)ans = ans * a;
        a = a * a;
        b /= 2;
    } return ans;
}
LL quick_pow(LL x, LL y) {
    LL ans = 1;
    while(y) {
        if(y & 1) {
            ans = ans * x % mod;
        } x = x * x % mod;
        y >>= 1;
    } return ans;
}
int a[maxn];
int b[maxn];
int d[maxn];
vector<int> vec;


int dp[605][605];
int main() {
#ifndef ONLINE_JUDGE
    FIN
#endif
    int T;
    scanf("%d", &T);
    while(T--) {
        vec.clear();
        int n;
        scanf("%d", &n);
        for(int i = 1; i <= n; i++) {
            scanf("%d%d%d", &a[i], &b[i], &d[i]);
            vec.push_back(a[i]);
            vec.push_back(b[i]);
        }
        sort(vec.begin(), vec.end());
        vec.erase(unique(vec.begin(), vec.end()), vec.end());
        int sz = vec.size();
        for(int i = 1; i <= n; i++) {
            a[i] = lower_bound(vec.begin(), vec.end(), a[i]) - vec.begin();
            b[i] = lower_bound(vec.begin(), vec.end(), b[i]) - vec.begin();
        }
        for(int cnt = 0; cnt < sz; cnt++) {
            for(int i = 0; i + cnt < sz; i++) {
                int pos = 0;
                int j = i + cnt;
                for(int k = 1;  k <= n; k++) {
                    if(a[k] >= i && b[k] <= j) {
                        if(pos == -1 || d[pos] < d[k]) {
                            pos = k;
                        }
                    }
                }
                if(pos == 0) {
                    dp[i][j] = 0;
                } else {
                    dp[i][j] = INF;
                    for(int k = a[pos]; k <= b[pos]; k++) {
                        dp[i][j] = min(dp[i][j], dp[i][k - 1] + dp[k + 1][j] + d[pos]);
                    }

                }
            }
        }
        printf("%d\n", dp[0][sz - 1]);
    }
    return 0;
}
每一个不曾刷题的日子 都是对生命的辜负 从弱小到强大,需要一段时间的沉淀,就是现在了 ~buerdepepeqi