zoukankan      html  css  js  c++  java
  • 湖南2020多校对抗赛round1 NWERC2014

    湖南2020多校对抗赛round1 NWERC2014

    题目来源:http://codeforces.com/gym/101482

    题号 赛中 赛后
    A Around the Track ×
    B Biking Duck ×
    C Cent Savings
    D Digi Comp II
    E Euclidean TSP
    F Finding Lines
    G Gathering ×
    H Hyacinth
    I Indoorienteering ×
    J Judging Troubles
    K Knapsack Collection ×

    C(动态规划):

    题意:

    给了你n个物品,每个物品的价值为pi,你最多可以将这n个物品分成d+1堆来购买这些物品,购买物品的规则是这样的,如果一堆物品的总价值为sum,那么购买这一堆物品的费用为sum的四舍五入的值,假设这一堆物品价值为126,那么购买他就需要130,假设这一堆物品价值为124,那么购买他就需要120元

    求,购买这n个物品最少花费多少钱

    题解:

    (dp[i][j]表示前i堆分成j堆最少需要花费多少钱)

    (边界:dp[i][1]=getval(sum[i]))

    (转移:dp[k][j] = min(dp[k][j], dp[i][j - 1] + getval(sum[k] - sum[i]));)

    (时间复杂度:O(d*n^2))

    #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("*********
    ")
    #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)<<"]
    "
    #define debug2(x,y) cout<<"["<<#x<<" "<<(x)<<" "<<#y<<" "<<(y)<<"]
    "
    #define debug3(x,y,z) cout<<"["<<#x<<" "<<(x)<<" "<<#y<<" "<<(y)<<" "<<#z<<" "<<z<<"]
    "
    #define debug4(x,y,z,m) cout<<"["<<#x<<" "<<(x)<<" "<<#y<<" "<<(y)<<" "<<#z<<" "<<z<<"]"<<" ["<<#m<<" "<<m<<"]
    "
    
    const int maxn = 2e3 + 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 dp[maxn][30];
    int a[maxn];
    int sum[maxn];
    int getval(int val) {
        if(val % 10 >= 5) {
            return val - val % 10 + 10;
        } else {
            return val - val % 10;
        }
    }
    int main() {
    #ifndef ONLINE_JUDGE
        FIN
    #endif
        int n, d;
        scanf("%d%d", &n, &d);
        for(int i = 1; i <= n; i++) {
            scanf("%d", &a[i]);
            sum[i] = sum[i - 1] + a[i];
        }
        memset(dp, INF, sizeof(dp));
        for(int i = 1; i <= n; i++) {
            dp[i][1] = getval(sum[i]);
            // debug1(dp[i][1]);
        }
    
        for(int i = 1; i <= n; i++) {
            for(int j = 2; j <= d + 1; j++) {
                for(int k = i + 1; k <= n; k++) {
                    dp[k][j] = min(dp[k][j], dp[i][j - 1] + getval(sum[k] - sum[i]));
                    // debug3(i, j, k);
                    // debug3(dp[k][i], dp[i][j - 1], getval(sum[k] - sum[i - 1]));
                }
            }
        }
        int ans = INF;
        for(int i = 1; i <= d + 1; i++) {
            // debug1  (dp[n][i]);
            ans = min(dp[n][i], ans);
        }
        printf("%d
    ", ans);
        return 0;
    }
    

    cwolf9定义状态是

    前i堆最多可以节省多少钱

    int n, m, k;
    int dp[MXN][21], ar[MXN], pre[MXN];
    int check(int a, int b) {
        int x = (pre[b]-pre[a]) % 10;
        int y = pre[b]-pre[a] - x;
        return (x>=5?x-10:x);
    }
    int main() {
    #ifndef ONLINE_JUDGE
        // freopen("D:\in.in", "r", stdin);
        // freopen("D:\out.out", "w", stdout);
    #endif
        n = read();
        m = read() + 1;
        for(int i = 1; i <= n; ++i) ar[i] = read(), pre[i] = pre[i-1] + ar[i];
        for(int i = 1; i <= n; ++i) for(int j = 1; j <= m; ++j) dp[i][j] = - INF;
        for(int i = 1; i <= n; ++i) {
            for(int j = 1; j <= min(m, i); ++j) {
                for(int k = 0; k < i; ++k) {
                    if(j == 1 && k > 0) continue;
                    if(k >= j - 1) {
                        dp[i][j] = max(dp[i][j], dp[k][j-1] + check(k, i));
                    }
                }
            }
        }
        int ans = INF;
        // printf("%d
    ", pre[n]);
        for(int i = 1; i <= m; ++i) {
            ans = min(ans, pre[n] - dp[n][i]);
            // printf("%d
    ", dp[n][i]);
        }
        printf("%d
    ", ans);
    #ifndef ONLINE_JUDGE
        cout << "time cost:" << 1.0 * clock() / CLOCKS_PER_SEC << "ms" << endl;
        system("pause");
    #endif
        return 0;
    }
    
    

    D(拓扑排序):

    题意:

    有m个传送门,传送门分左右两边,每个传送门初始时都有一个状态“L”或者"R",现在有n个小球从1号节点出发,每到一个传送门就会被传送到传送门当前状态指向的节点,每次传送门传送完一个小球后就会将当前状态反转,保证可以到达终点0,问m个传送门最后的状态是怎么样的

    题解:

    可以解得,如果传送门被经过了奇数次,那么传送门的状态就会反转,否则传送门就不会改变状态,所以拓扑排序一遍后记录每个传送门被经过的次数就行了

    #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("*********
    ")
    #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)<<"]
    "
    #define debug2(x,y) cout<<"["<<#x<<" "<<(x)<<" "<<#y<<" "<<(y)<<"]
    "
    #define debug3(x,y,z) cout<<"["<<#x<<" "<<(x)<<" "<<#y<<" "<<(y)<<" "<<#z<<" "<<z<<"]
    "
    const int maxn = 5e5 + 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 node {
        int l, r;
        char sta[3];
    } a[maxn];
    int vis[maxn];
    int in[maxn];
    LL num[maxn];
    int main() {
    #ifndef ONLINE_JUDGE
        FIN
    #endif
        LL n;
        int m;
        scanf("%lld%d", &n, &m);
        for(int i = 1; i <= m; i++) {
            scanf("%s %d %d", a[i].sta, &a[i].l, &a[i].r);
            in[a[i].l]++;
            in[a[i].r]++;
        }
        queue<int> q;
    
        num[1] = n;
        for(int i = 1; i <= m; i++) {
            if(in[i] == 0) {
                q.push(i);
            }
        }
        while(!q.empty()) {
            int u = q.front();
            q.pop();
            if(num[u] % 2 == 1) vis[u] = 1;
            if(a[u].sta[0] == 'L') {
                num[a[u].l] += (num[u] - num[u] / 2);
                num[a[u].r] += num[u] / 2;
            } else {
                num[a[u].r] += (num[u] - num[u] / 2);
                num[a[u].l] += num[u] / 2;
            }
            in[a[u].l]--;
            if(in[a[u].l] == 0) {
                q.push(a[u].l);
            }
            in[a[u].r]--;
            if(in[a[u].r] == 0) {
                q.push(a[u].r);
            }
        }
        for(int i = 1; i <= m; i++) {
            if(vis[i] == 1) {
                if(a[i].sta[0] == 'L') {
                    a[i].sta[0] = 'R';
                } else {
                    a[i].sta[0] = 'L';
                }
            }
        }
        for(int i = 1; i <= m; i++) {
            printf("%c", a[i].sta[0]);
        }
        printf("
    ");
        return 0;
    }
    
    

    E(三分):

    题意:

    根据题目给的公式和例可以猜出来time t=第二个公式的值和第三个公式的值

    然后再反过去读题就知道

    ((n * pow(log2(n), c * sqrt(2))) / (p * 1e9);)

    (s * (1 + 1.0 / c) / v;)

    分别是题目给你的两个公式,第一个公式是一个关于c递增的公式,第二个公式是一个关于c递减的公式

    那么时间的最小值是根据c来的,我们需要找到波谷

    所以这里就可以想到是三分求波谷了

    #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("*********
    ")
    #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)<<"]
    "
    #define debug2(x,y) cout<<"["<<#x<<" "<<(x)<<" "<<#y<<" "<<(y)<<"]
    "
    #define debug3(x,y,z) cout<<"["<<#x<<" "<<(x)<<" "<<#y<<" "<<(y)<<" "<<#z<<" "<<z<<"]
    "
    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 n, m, k;
    double p, s, v, c, t;
    double first(double c) {
        return n * pow(log(n), c * sqrt(2));
    }
    double second(double c) {
        return (n * pow(log2(n), c * sqrt(2))) / (p * 1e9);
    }
    double third(double c) {
        return s * (1 + 1.0 / c) / v;
    }
    double get(double c) {
        return second(c) + third(c);
    }
    int main() {
    #ifndef ONLINE_JUDGE
        FIN
    #endif
        cin >> n >> p >> s >> v;
        double l = 0, r = 100, ans = 1e18, c;
        int T = 100;
        while(T--) {
            double lmid = l + (r - l) / 3.0;
            double rmid = r - (r - l) / 3.0;
            double Lans = get(lmid), Rans = get(rmid);
            if(Rans > Lans) {
                r = rmid;
                if(ans > Lans) ans = Lans, c = lmid;
            } else {
                l = lmid;
                if(ans > Rans) ans = Rans, c = rmid;
            }
        }
        printf("%.9f %.9f
    ", ans, c);
        return 0;
    }
    

    F(随机):

    题意:

    平面上有n个点,问是否存在[n · p/100]向上取整个点在同一条直线上面

    随机大法

    证明如下:

    [假设这条直线存在 \ 那么平面上就有n*p\%个以上的点就在直线上\ 1.我们可以知道随便取出一个点,那么这个点在直线上的概率是p/100;\ 2.随机选出两个点,那么这两个点都在直线上的概率就是p*p/10000;\ 3.随机出来的两个点不在直线上的概率是(1-p*p/10000);\ 4.随机k次出来两个点不在这条直线上的概率是(1-p*p/10000)^k\ 5.所以随机的正确率是1-(1-p*p/10000)^k=(0.99999999999999999813261855332981‬)\ ]

    #include <bits/stdc++.h>
    #define lson l,m,rt<<1
    #define rson m+1,r,rt<<1|1
    #define x first
    #define y second
    #define rep(i,a,b) for(int i=a;i<b;++i)
    #define per(i,a,b) for(int i=a-1;i>=b;--i)
    #define fuck(x) cout<<'['<<#x<<' '<<(x)<<']'
    #define eps 1e-8
    using namespace std;
    typedef long long ll;
    typedef unsigned long long ull;
    typedef unsigned int ui;
    typedef pair<int, int> PII;
    const int MX = 1e6;
    const int MM = 1e4;
    
    namespace random {
        typedef unsigned ui;
        typedef long long ll;
        typedef unsigned long long ull;
        ui X, Y, Z, W; string str;
        char in[15], ou[15];
        void start() {
            srand ( (ui) time (NULL) );
            X = rand(), Y = X ^ rand(), Z = Y ^ rand();
        }
        ui RNG61() {
            X = X ^ (X << 11);
            X = X ^ (X >> 4);
            X = X ^ (X << 5);
            X = X ^ (X >> 14);
            W = X ^ Y ^ Z;
            X = Y;
            Y = Z;
            Z = W;
            return Z;
        }
        int Randint (int mod) {
            return RNG61() % mod + 1;
        }
        ll Randll(ll mod) {
            return ((ull)RNG61() << 32 | RNG61()) % mod + 1;
        }
        double Randdouble(int l, int r) {
            if(l == r) return l;
            if(l > r) swap(l, r);
            double ret = RNG61() % (r - l) + l;
            double tmp = RNG61();
            while(tmp > 1) tmp /= 10;
            ret += tmp;
            return ret;
        }
    }
    const int maxn = 1e5 + 5;
    struct Point {
        int x, y;
    } a[maxn];
    bool check(Point t1, Point t2, Point t3) {
        int x1 = t1.x;
        int x2 = t2.x;
        int x3 = t3.x;
        int y1 = t1.y;
        int y2 = t2.y;
        int y3 = t3.y;
        if((y2 - y1) * (x3 - x2) == (y3 - y2) * (x2 - x1)) {
            return true;
        }
        return false;
    }
    using namespace random;
    int main() {
        int n, p;
        scanf("%d%d", &n, &p);
        for(int i = 1; i <= n; i++) {
            scanf("%d%d", &a[i].x, &a[i].y);
        }
        int num = (n * p + 99) / 100;
        start();
        int T = 1000;
        int flag = 0;
        while(T--) {
            int x = Randint(n);
            int y = Randint(n);
            if(x == y) {
                y = x + 1;
            }
            Point t1 = a[x];
            Point t2 = a[y];
            int cnt = 0;
            for(int i = 1; i <= n; i++) {
                if(check(t1, t2, a[i])) {
                    cnt++;
                }
            }
            if(cnt >= num) {
                flag = 1;
            }
        }
        if(flag) {
            printf("possible
    ");
        } else {
            printf("impossible
    ");
        }
    }
    
    

    H(贪心+dfs):

    题意:

    每个节点可以有一段波分的频率

    如果两个相邻的节点有相同的频率,那么就可以使用其中的一个频率通信

    现在给你一颗n个节点形成的树,现在让你给每个节点构造一段他自己的频率,使得,总的在使用中的频率个数最多,并且每个相邻的节点都要可以通信

    题解:

    要想在使用中的节点最多,那么每个频率至少用一次,假设a节点用了这个频率,那么他的所有儿子节点都要用上这个频率,可以先构造根节点的频率为【1 ,2】,然后从根节点往下走给每个子节点赋值和新建频率即可,这样可以保证在使用中的频率个数一定是最高的

    #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("*********
    ")
    #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)<<"]
    "
    #define debug2(x,y) cout<<"["<<#x<<" "<<(x)<<" "<<#y<<" "<<(y)<<"]
    "
    #define debug3(x,y,z) cout<<"["<<#x<<" "<<(x)<<" "<<#y<<" "<<(y)<<" "<<#z<<" "<<z<<"]
    "
    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 EDGE {
        int v, nxt;
    } edge[maxn << 1];
    int head[maxn], tot;
    void init() {
        memset(head, -1, sizeof(head));
        tot = 0;
    }
    void add_edge(int u, int v) {
        edge[tot].v = v;
        edge[tot].nxt = head[u];
        head[u] = tot++;
    }
    struct node {
        int x, y;
    } a[maxn];
    int in[maxn];
    int vis[maxn];
    int cnt = 2;
    void dfs(int u, int fa) {
        if(u == 1) {
            for(int i = head[u]; i != -1; i = edge[i].nxt) {
                int v = edge[i].v;
                if(v == fa) continue;
                dfs(v, u);
            }
        } else {
            if(in[u] == 1 && u != 1) {
                a[u].x = a[fa].x;
                a[u].y = a[fa].y;
                vis[a[u].x]++;
                vis[a[u].y]++;
                return;
            }
            if(vis[a[fa].x] >= 2) {
                a[u].x = a[fa].y;
            } else {
                a[u].x = a[fa].x;
            }
            a[u].y = ++cnt;
            vis[a[u].x]++;
            vis[a[u].y]++;
            for(int i = head[u]; i != -1; i = edge[i].nxt) {
                int v = edge[i].v;
                if(v == fa) continue;
                dfs(v, u);
            }
        }
    }
    
    int main() {
    #ifndef ONLINE_JUDGE
        FIN
    #endif
        int n;
        scanf("%d", &n);
        init();
        for(int i = 1, u, v; i < n; i++) {
            scanf("%d%d", &u, &v);
            add_edge(u, v);
            add_edge(v, u);
            in[u]++;
            in[v]++;
        }
    
        a[1].x = 1;
        a[1].y = 2;
        vis[a[1].x]++;
        vis[a[1].y]++;
        cnt = 2;
        dfs(1, 0);
        for(int i = 1; i <= n; i++) {
            printf("%d %d
    ", a[i].x, a[i].y);
        }
        return 0;
    }
    
    

    J(签到):

    题意:

    你有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("*********
    ")
    #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)<<"]
    "
    #define debug2(x,y) cout<<"["<<#x<<" "<<(x)<<" "<<#y<<" "<<(y)<<"]
    "
    #define debug3(x,y,z) cout<<"["<<#x<<" "<<(x)<<" "<<#y<<" "<<(y)<<" "<<#z<<" "<<z<<"]
    "
    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;
    }
    map<string, int>mp1, mp2;
    
    int main() {
    #ifndef ONLINE_JUDGE
        FIN
    #endif
        int n;
        scanf("%d", &n);
        for(int i = 1; i <= n; i++) {
            string str;
            cin >> str;
            mp1[str]++;
        }
        for(int i = 1; i <= n; i++) {
            string str;
            cin >> str;
            mp2[str]++;
        }
        map<string, int>::iterator it;
        int ans = 0;
        for(it = mp1.begin(); it != mp1.end(); it++) {
            ans += min(mp1[it->first], mp2[it->first]);
        }
        printf("%d
    ", ans);
        return 0;
    }
    
    

    K(找规律+模拟):

    题意:

    有一个长度为s的圆形轮盘,有s个槽位,有n个行李箱在这些槽位上分布着,你可以站着某个槽位前取行李,取一个行李需要你花费t 的时间,每次只能取一个行李,轮盘每秒钟走一个单位长度,s-1和0的位置是连着的,问你取完所有的行李花费的最小时间、最大时间、平均时间是多少。

    题解:

    因为位置s特别大,可以对于每一个位置花费的总的时间打一个表,可以发现,如果原来的位置t上面有行李,而位置t+1上面没有行李的话,花费的时间是递减的,也就是说我们计算平均时间可以用到等差数列,因为n只有2000,所以我们可以对于每一个行李的位置都计算一遍时间,这样就可以知道所有位置的时间了

    代码:

    #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("*********
    ")
    #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)<<"]
    "
    #define debug2(x,y) cout<<"["<<#x<<" "<<(x)<<" "<<#y<<" "<<(y)<<"]
    "
    #define debug3(x,y,z) cout<<"["<<#x<<" "<<(x)<<" "<<#y<<" "<<(y)<<" "<<#z<<" "<<z<<"]
    "
    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 n, s, t;
    LL tim[maxn];
    LL cal(int x) {
        LL ret = 0; int p = x;
        multiset<int> st;
        multiset<int>::iterator it;
        for(int i = 1; i <= n; ++i) st.insert(a[i]);
        while(!st.empty()) {
            it = st.lower_bound(p);
            if(it == st.end()) {
                ret += s - p;
                p = 0;
                it = st.lower_bound(p);
            }
            ret += (*it) - p + t;
            p = ((*it) + t) % s;
            st.erase(it);
        }
        return ret;
    }
    int main() {
    #ifndef ONLINE_JUDGE
        FIN
    #endif
    
        scanf("%d%d%d", &n, &s, &t);
        for(int i = 1; i <= n; i++) {
            scanf("%d", &a[i]);
        }
        sort(a + 1, a + 1 + n);
        a[0] = -2;
        LL sum = 0;
        for(int i = 1; i <= n; ++i) {
            if(a[i] == a[i - 1]) tim[i] = tim[i - 1];
            else {
                tim[i] = cal(a[i]);
            }
        }
        LL mn = tim[1], mx = tim[1];
        for(int i = 2; i <= n; ++i) {
            mn = min(mn, tim[i]);
            mx = max(mx, tim[i]);
        }
        for(int i = 1; i <= n; ++i) {
            if(a[i] == a[i - 1]) continue;
            int l = a[i - 1] + 1, r = a[i];
            if(l == -1) l = a[n] + 1, r += s;
            int len = r - l + 1;
            mx = max(mx, tim[i] + len - 1);
            sum += 1ll * (tim[i] + tim[i] + len - 1) * len / 2;
        }
        cout << mn << endl;
        cout << mx << endl;
        LL gcd = __gcd(sum, 1ll * s);
        sum /= gcd;
        s /= gcd;
        cout << sum << '/' << s << endl;    return 0;
    }
    
  • 相关阅读:
    《党务管理信息系统的设计与实现》论文笔记(八)
    《高校党务信息系统的研究与分析》论文笔记(七)
    《用分布式多层应用技术开发党务管理信息系统》论文笔记(六)
    《二级学院《党务管理信息系统》的使用管理》论文笔记(五)
    《某学院党务管理信息系统的研究与设计》论文笔记(四)
    《数据结构课程现代教学中基于Web题库管理系统设计与实现》论文笔记(十)
    《课程管理系统的设计与实现》论文笔记(九)
    《基于微信平台的课程管理系统设计》论文笔记(八)
    《基于SSH框架的课程管理系统的设计与实现》论文笔记(七)
    《基于Android平台的大学生课程计划管理系统》论文笔记(六)
  • 原文地址:https://www.cnblogs.com/buerdepepeqi/p/12733707.html
Copyright © 2011-2022 走看看