湖南2020多校对抗赛round3 CERC2014
湖南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;
}

 
                
            
         
         浙公网安备 33010602011771号
浙公网安备 33010602011771号