hihocoder编程练习赛60

先看下题目吧
题目1 : hohahola
时间限制:10000ms
单点时限:1000ms
内存限制:256MB
描述
有一种叫作hohahola的饮料,售价是X元一瓶。小Hi非常喜欢这种饮料,但是他现在身无分文。

不过小Hi有N张优惠券,买hohahola时每瓶最多使用一张优惠券,可以使该瓶价格减少Y元。(Y ≤ X)

同时优惠券可以出售,小Hi每出售一张优惠券可以获得Z元。

请你帮小Hi计算通过出售若干优惠券,他最多可以买多少瓶hohahola。

输入
一行4个整数N, X, Y, Z。

1 ≤ N, Z ≤ 1000000000 1 ≤ Y ≤ X ≤ 1000000000

输出
一个整数表示答案

样例输入
100 3 2 1
样例输出
50
这题我直接把函数写出来了,求个极值就好,不过要注意z-y有可能小于0或大于0.不过看了大佬的代码,他们好像是二分,我直接就把答案写出来了。

#include<bits/stdc++.h>
using namespace std;
long long n,x,y,z;
int main()
{
    cin >> n >> x >> y >> z;
    long long ans;
    double t = 1.0 * z / (x - y) + 1;
    double temp2 = n / t;
    long long temp1 = z * temp2 / (x - y);
    ans = temp1;
    if(z - y >= 0)
        ans = z * n / x;
    cout << ans;
}

1745 : 最大顺子

时间限制:10000ms
单点时限:1000ms
内存限制:256MB
描述
你有N张卡片,每张卡片上写着一个正整数Ai,并且N张卡片上的整数各不相同。

此外,你还有M张百搭卡片,可以当作写着任意正整数的卡片。

一个“顺子”包含K张卡片,并且满足卡片上的整数恰好是连续的K个正整数。我们将其中最大的整数称作顺子的值。

例如1-2-3-4-5的值是5,101-102-103的值是103。

请你计算用给定的N张卡片和M张百搭卡片,能凑出的值最大的顺子是多少,并且输出该顺子的值。

输入
第一行包含3个整数,N,M和K。

第二行包含N个整数,A1, A2, … AN。

对于50%的数据,1 ≤ N, K ≤ 1000

对于100%的数据,1 ≤ N, K ≤ 100000 0 ≤ M < K

输出
一个整数代表答案

样例输入
10 1 5
1 4 2 8 5 7 10 11 13 3
样例输出
11
这题也不难,县排序,倒着查找,arr[i]与arr[i] + k之间需要填充的数小于m是就行了。

#include<bits/stdc++.h>
using namespace std;
int n,m,k,arr[100001],d[100001] = {0};
vector<int> v;
int main()
{
    cin >> n >> m >> k;
    for(int i = 1;i <= n;++i)
        cin >> arr[i];
    sort(arr + 1,arr + n + 1);
    int ans = 0,i = n;
    for(int j = n;i > 0;--i)
    {
        while(arr[i] + k - 1 < arr[j])
            --j;
        if(j - i + 1 >= k - m)
            break;
    }
    ans = arr[i] + k - 1;
    cout << ans;
}

1746 : 路径包含问题

时间限制:10000ms
单点时限:1000ms
内存限制:256MB
描述
给定一棵N的节点的树,节点编号1~N,并且1号节点是根节点。

小Hi会反复询问小Ho一个问题:给定两个节点a和b,有多少对节点c和d满足c < d且c到d的路径包含完整的a到b的路径?

你能帮帮小Ho吗?

输入
第一行包含两个数N和M,依次是节点总数和问题总数。

第2~N行每行包含两个整数u和v,代表u是v的父节点。

以下M行每行包含两个整数a和b,代表一个问题。

对于30%的数据,1 ≤ N, M ≤ 1000

对于100%的数据,1 ≤ N, M ≤ 100000

输出
对于每个问题输出一个整数,代表答案。

样例输入
7 2
1 2
1 3
2 4
2 5
3 6
3 7
2 3
2 4
样例输出
9
6
这题就是lca问题,用倍增法解决

#include<bits/stdc++.h>
using namespace std;
int n,m,depth[100001],ancestor[21][100001]= {0};
long long sum[100001] = {0};
vector<int> child[100001];
int dfs(int num,int d)
{
    sum[num] = 1;
    for(int i = 0;i < (signed)child[num].size();++i)
    {
        depth[child[num][i]] = d + 1;
        sum[num] += dfs(child[num][i],d + 1);
    }
    return sum[num];
}
int main()
{
    cin >> n >> m;
    for(int i = 2;i <= n;++i)
    {
        int temp1,temp2;
        cin >> temp1 >> temp2;
        child[temp1].push_back(temp2);
        ancestor[0][temp2] = temp1;
    }
    depth[1] = 1;
    dfs(1,1);
    for(int i = 1;i <= 20;++i)
        for(int j = 1;j <= n;++j)
            ancestor[i][j] = ancestor[i - 1][ancestor[i - 1][j]];
    while(m)
    {
        int temp1,temp2;
        cin >> temp1 >> temp2;
        if(depth[temp1] < depth[temp2])
            swap(temp2,temp1);
        int j = 20,t = temp1;
        while(j >= 0 && depth[temp2] + 1 <= depth[temp1])
        {
            //cout << j;
            if(ancestor[j][temp1] && depth[ancestor[j][temp1]] > depth[temp2])
                temp1 = ancestor[j][temp1];
            --j;
        }
        long long ans;
        if(ancestor[0][temp1] != temp2)
            ans = sum[t] * sum[temp2];
        else
            ans = (sum[1] - sum[temp1]) * sum[t];
        cout << ans << endl;
        --m;
    }
    return 0;
}

第四题暂时还没有做出来

点赞