码迷,mamicode.com
首页 > 其他好文 > 详细

2019 杭电多校 第八场

时间:2019-08-29 11:13:21      阅读:107      评论:0      收藏:0      [点我收藏+]

标签:bash   思路   clu   题意   double   key   min   tle   problem   

2019 Multi-University Training Contest 8

补题链接:2019 Multi-University Training Contest 8

1003 Acesrc and Good Numbers HDU 6659

题意

定义 \(f(d, n)\) 为十进制下 \(1\)\(n\) 所有数的数位中数字 \(d\) 出现的次数。给定 \(x\),找出最大的 \(n(n \le x)\) 满足 \(f(d, n) = n\)

题解

看到了一个神仙做法。

显然如果 \(f(d, x) = x\) 时就直接输出。

否则,需要缩小 \(x\)。令 \(f(d, x) = y\),则需要将 \(x\) 缩小 \(\lceil \frac{|x - y|}{18} \rceil\)。即 \(x = x - abs(f(d, x) - x) / 18\)。原因是 \(f(d, x)\)\(f(d, x - 1)\) 最多相差 \(18\)\(d\) \(\ (e.g. \ f(9, 10^{18}-1)\ to\ f(9, 10^{18}-2))\)

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;

// 计算 1 到 n 中数字 x 出现的次数
ll f(ll d, ll n) {
    ll cnt = 0, k;
    for (ll i = 1; k = n / i; i *= 10) {
        cnt += (k / 10) * i;
        int cur = k % 10;
        if (cur > d) {
            cnt += i;
        }
        else if (cur == d) {
            cnt += n - k * i + 1;
        }
    }
    return cnt;
}

int main() {
    ios::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);
    int T;
    cin >> T;
    while (T--) {
        ll d, x;
        cin >> d >> x;
        while (true) {
            ll num = f(d, x);
            if (num == x) {
                cout << x << endl;
                break;
            } else {
                x -= max(1LL, abs(num - x) / 18);
            }
        }
    }
    return 0;
}

参考

2019 Multi-University Training Contest 8——Acesrc and Good Numbers(数学 想法)

1009 Calabash and Landlord HDU 6665

题意:

给出两个矩形,求矩形把平面分割成几块。

思路

分类讨论

技术图片

听说只要离散化到 \(5*5\) 的格子里然后 \(DFS\) 就可以了,有空再补。

#include <bits/stdc++.h>
using namespace std;

typedef long long ll;

const ll inf = 0x3f3f3f3f;

struct Point
{
    ll x, y;
}p[10];


int main() {
    int T;
    cin >> T;
    while (T--) {
        ll maxx = 0, maxy = 0, minx = inf, miny = inf;
        for(int i = 1; i <= 2; ++i) {
            scanf("%lld%lld", &p[i].x, &p[i].y);
        }
        p[3].x = p[1].x;
        p[3].y = p[2].y;
        p[4].x = p[2].x;
        p[4].y = p[1].y;
        ll s1 = (p[2].x - p[1].x) * (p[2].y - p[1].y);

        for(int i = 5; i <= 6; ++i) {
            scanf("%lld%lld", &p[i].x, &p[i].y);
        }
        p[7].x = p[5].x;
        p[7].y = p[6].y;
        p[8].x = p[6].x;
        p[8].y = p[5].y;
        ll s2 = (p[6].x - p[5].x) * (p[6].y - p[5].y);

        for(int i = 1; i <= 8; ++i) {
            maxx = max(maxx, p[i].x);
            maxy = max(maxy, p[i].y);
            minx = min(minx, p[i].x);
            miny = min(miny, p[i].y);
        }

        // for(int i = 1; i <= 8; ++i) {
        //     cout << p[i].x << " " << p[i].y << endl;
        // }

        if(p[1].x == p[5].x && p[1].y == p[5].y && p[3].x == p[7].x && p[3].y == p[7].y && p[6].x == p[2].x && p[6].y == p[2].y && p[4].x == p[8].x && p[4].y == p[8].y) {
            printf("2\n");
            continue;
        }
        ll s = (maxx - minx) * (maxy - miny); // cout << s << endl;
        if(s1 == s || s2 == s) {
            if((p[1].x == p[5].x && p[2].x == p[6].x)) {
                if(p[5].y == p[1].y || p[6].y == p[2].y) printf("3\n");
                else printf("4\n");
            } else if((p[1].y == p[5].y && p[2].y == p[6].y)) {
                if(p[5].x == p[1].x || p[6].x == p[2].x) printf("3\n");
                else printf("4\n");
            }
            else printf("3\n");
        } else if(p[4].y >= p[7].y || p[8].y >= p[3].y || p[5].x >= p[2].x || p[1].x >= p[6].x) {
            printf("3\n");
        } else if((p[2].x - p[1].x) * (p[6].y - p[5].y) == s) {
            if(p[6].y > p[2].y && p[5].y < p[1].y && p[1].x < p[5].x && p[2].x > p[6].x) {
                printf("6\n");
            } else if(p[1].x == p[5].x && p[1].y == p[5].y) {
                printf("4\n");
            } else if(p[3].x == p[7].x && p[3].y == p[7].y) {
                printf("4\n");
            } else if(p[2].x == p[6].x && p[2].y == p[6].y) {
                printf("4\n");
            } else if(p[4].x == p[8].x && p[4].y == p[8].y) {
                printf("4\n");
            } else {
                printf("5\n");
            }
        } else if((p[6].x - p[5].x) * (p[2].y - p[1].y) == s) {
            if(p[2].y > p[6].y && p[1].y < p[5].y && p[5].x < p[1].x && p[6].x > p[2].x) {
                printf("6\n");
            } else if(p[1].x == p[5].x && p[1].y == p[5].y) {
                printf("4\n");
            } else if(p[3].x == p[7].x && p[3].y == p[7].y) {
                // cout << 1 << endl;
                printf("4\n");
            } else if(p[2].x == p[6].x && p[2].y == p[6].y) {
                printf("4\n");
            } else if(p[4].x == p[8].x && p[4].y == p[8].y) {
                printf("4\n");
            } else {
                printf("5\n");
            }
        } else {
            printf("4\n");
        }
    }
    
    return 0;
}

1010 Quailty and CCPC HDU 6666

签到题。

#include <bits/stdc++.h>
using namespace std;

typedef long long ll;

const int maxn = 1e6 + 10;

struct Team
{
    char name[20];
    ll p, t;
} te[maxn];

int cmp(Team t1, Team t2) {
    if(t1.p == t2.p) return t1.t < t2.t;
    return t1.p > t2.p;
}

int main() {
    int T;
    cin >> T;
    while(T--) {
        int n;
        int d;
        scanf("%d%d", &n, &d);
        for(int i = 0; i < n; ++i) {
            scanf("%s%lld%lld", &te[i].name, &te[i].p, &te[i].t);
        }
        sort(te, te + n, cmp);
        // d *= 0.1;
        // double l = floor(d * n), r = ceil(d * n);
        // double de = d * n - floor(d * n);
        if((d * n) % 10 == 5) {
            int ans = d * n / 10;
            printf("%s\n", te[ans].name);
        } else {
            printf("Quailty is very great\n");
        }
    }
    return 0;
}

1011 Roundgod and Milk Tea HDU 6667

题意:

\(n\) 个班级,每个班有 \(a_i\) 个人,做了 \(b_i\) 杯奶茶,每个班的每个人最多喝一杯奶茶且不能和自己班做的奶茶,问最多共有多少人喝到奶茶。

思路

最初的想法是用一个 \(sum\) 记录所有剩余的奶茶数,然后每个组能喝的奶茶数为 \(sum\ -\) 该组的奶茶(自己不能喝自己的) \(+\) 上一组做的奶茶 (上一组减掉的加回来)。后来发现有点问题,就是中间一步减掉自己的奶茶可能是减多的,也就是上一组喝掉的可能就是当前组的奶茶,那么当前组剩余的奶茶是比原来少的,于是就用 \(tmp2\) 保存上一组喝掉的奶茶数,每次让上一组喝掉当前组的奶茶,如果不够喝再用 \(tmp\) 保存还要喝掉的奶茶数,往下迭代。

#include <bits/stdc++.h>
using namespace std;

typedef long long ll;

const int maxn = 1e6 + 10;

struct Team
{
    ll m, n;  // 人数 奶茶数
} t[maxn];

int cmp(Team t1, Team t2) {
    return t1.m > t2.m;
}

int main() {
    int T;
    cin >> T;
    while(T--) {
        int n;
        scanf("%d", &n);
        ll sum = 0;
        for(int i = 0; i < n; ++i) {
            scanf("%lld%lld", &t[i].m, &t[i].n);
            sum += t[i].n;
        }
        sort(t, t + n, cmp);
        ll ans = 0; 
        ll tmp = t[0].n; // tmp 保存喝掉的奶茶数 第一组一定要被喝
        ll tmp2 = 0; // tmp2 保存的是上一组喝掉的奶茶
        for(int i = 0; i < n; ++i) {
            if(i) {
                // 上一组喝掉的奶茶数+之前喝掉的奶茶数
                if(t[i].n < tmp2 + tmp) {
                    t[i].n = 0;
                    tmp = tmp2 + tmp - t[i].n;
                } else {
                    t[i].n = t[i].n - (tmp2 + tmp);
                    tmp = 0;
                }
            }
            sum -= t[i].n; // 自己不能喝自己的奶茶
            if(i) sum += t[i - 1].n; // 可以喝上一组的奶茶
            // 剩余的奶茶数与第 i 组人数比较
            if(sum >= t[i].m) {
                ans += t[i].m;
                sum -= t[i].m;
                tmp2 = t[i].m;
            } else {
                ans += sum;
                sum -= sum;
                tmp2 = sum;
            }
            // cout << ans << endl;
        }
        printf("%lld\n", ans);
    }
    return 0;
}

比赛中完全想复杂了,其实完全可以很快处理。把每个人能喝的奶茶加起来和所有的奶茶比较即可。

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn = 1e6 + 10;

ll a[maxn], b[maxn];

int main() {
    int T;
    scanf("%d", &T);
    while(T--) {
        int n;
        scanf("%d", &n);
        ll sum = 0;
        for(int i = 0; i < n; ++i) {
            scanf("%lld%lld", &a[i], &b[i]);
            sum += b[i];
        }
        ll ans = 0;
        for(int i = 0; i < n; ++i) {
            ans += min(a[i], sum - b[i]);
        }
        printf("%lld\n", min(ans, sum));
    }
    return 0;
}

2019 杭电多校 第八场

标签:bash   思路   clu   题意   double   key   min   tle   problem   

原文地址:https://www.cnblogs.com/wulitaotao/p/11428343.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!