Codeforces Round #748 (Div. 3)

Codeforces Round #748 (Div. 3)

A. Elections

思路分析:
  • 令当前值比最大值大即可,如果最大值是它自己,就输出 0 0 0
代码
#include <bits/stdc++.h>
using namespace std;
pair<int, int> a[3];
int ans[3];
int main()
{
        ios::sync_with_stdio(0);
        cin.tie(0);
        cout.tie(0);
        int t;
        cin >> t;
        while (t--)
        {
                for (int i = 0; i < 3; i++)
                        cin >> a[i].first, a[i].second = i;
                sort(a, a + 3);
                for (int i = 0; i < 3; i++)
                {
                        if (i == 0)
                        {
                                ans[a[i].second] = a[2].first - a[0].first + 1;
                        }
                        else if (i == 1)
                        {
                                ans[a[i].second] = a[2].first - a[1].first + 1;
                        }
                        else
                        {
                                if (a[2].first == a[1].first)
                                {
                                        ans[a[i].second] = 1;
                                }
                                else
                                        ans[a[i].second] = 0;
                        }
                }
                for (int i = 0; i < 3; i++)
                {
                        cout << ans[i] << ' ';
                }
                cout << endl;
        }
        return 0;
} 

B. Make it Divisible by 25

思路分析:
  • 一开始以为和上次make power of 2一样,然后发现不对劲,想到了结论,25是5的倍数,那么我们剩下的数最后一位必定为5或者0,所以我们一直删到最后一位为5或者0为止。
  • 然后如果为25的倍数的话,末尾两位必定是25,50,75,00,所以我们就分情况取最小值即可。
  • 其实官方题解的最简单,我就建议不要看我这个做法了。
代码
#include <bits/stdc++.h>
using namespace std;
int a[2] = {2, 7};
int main()
{
        ios::sync_with_stdio(0);
        cin.tie(0);
        cout.tie(0);
        int t;
        cin >> t;
        while (t--)
        {
                string s;
                cin >> s;
                string c = s;
                int mincnt = 0;
                //以5为最后一位
                for (int i = s.size() - 1; i >= 0; i--)
                {
                        if (s[i] != '5')
                        {
                                s.erase(i);
                                mincnt++;
                        }
                        //找到5
                        else
                                break;
                }
                for (int i = s.size() - 2; i >= 0; i--)
                {
                        if (s[i] != '2' && s[i] != '7')
                        {
                                mincnt++;
                                s.erase(i);
                        }
                        else
                                break;
                }
                int temp = 0;
                for (int i = c.size() - 1; i >= 0; i--)
                {
                        if (c[i] != '0')
                        {
                                c.erase(i);
                                temp++;
                        }
                        //找到5
                        else
                                break;
                }
                for (int i = c.size() - 2; i >= 0; i--)
                {
                        if (c[i] != '5' && c[i] != '0')
                        {
                                temp++;
                                c.erase(i);
                        }
                        else
                                break;
                }
                cout << min(mincnt, temp) << endl;
        }
        return 0;
}

C. Save More Mice

思路分析:
  • 这题其实就是贪心吧,让离洞最近的老鼠先逃即可,因为老鼠和猫的相对速度为 1 1 1
  • 注意更新猫的位置即可。
代码
#include <bits/stdc++.h>
using namespace std;
vector<int> a;
int main()
{
        ios::sync_with_stdio(0);
        cin.tie(0);
        cout.tie(0);
        int t;
        cin >> t;
        while (t--)
        {
                a.clear();
                int n, k;
                cin >> n >> k;
                for (int i = 0; i < k; i++)
                {
                        int x;
                        cin >> x;
                        a.push_back(x);
                }
                sort(a.begin(), a.end());
                int ans = 0;
                int x = 0;
                for (int i = a.size() - 1; i >= 0; i--)
                {
                        if (x < a[i])
                        {
                                x += (n - a[i]);
                                ans++;
                        }
                        else
                                break;
                }
                cout << ans << endl;
        }
        return 0;
}

D1. All are Same

思路分析:
  • 因为最后要把所有数变为一个数,那么肯定是把所有数变成当前数组的最小值即可。
  • 那么如何求这个减去的数的最大值呢?
  • 实际上也就是所有数和最小值的GCD了。
代码
#include <bits/stdc++.h>
using namespace std;
int main()
{
        ios::sync_with_stdio(0);
        cin.tie(0);
        cout.tie(0);
        int t;
        cin >> t;
        while (t--)
        {
                int n;
                cin >> n;
                vector<int> a(n);
                for (int i = 0; i < n; i++)
                {
                        cin >> a[i];
                }
                sort(a.begin(), a.end());
                int x = a[0];
                int ans = 0;
                for (int i = 0; i < n; i++)
                {
                        ans = __gcd(ans, a[i] - x);
                }
                if (ans != 0)
                        cout << ans << endl;
                else
                {
                        cout << "-1" << endl;
                }
        }
        return 0;
}

D2. Half of Same

思路分析:
  • 我们可以知道当且仅当当前数组中已经有 n / 2 n / 2 n/2个数相同输出 − 1 -1 1
  • 我们枚举每一个数,也就是说把其他数变为它需要减去多少值保存一下,然后记录原数组中已经有多少个数与它相同,再因数分解一下这个差值,然后遍历它的差值的因数,取使得因数的个数加上原本和它一样的数的个数大于 n / 2 n / 2 n/2的最大的因数即可。
代码
#include <bits/stdc++.h>
using namespace std;
set<int> divide(int x)
{
        set<int> q;
        for (int i = 1; i * i <= x; i++)
        {
                if (x % i == 0)
                {
                        q.insert(i);
                        q.insert(x / i);
                }
        }
        return q;
}
int main()
{
        ios::sync_with_stdio(0);
        cin.tie(0);
        cout.tie(0);
        int t;
        cin >> t;
        while (t--)
        {
                int n;
                cin >> n;
                vector<int> a(n);
                for (int i = 0; i < n; i++)
                {
                        cin >> a[i];
                }
                int k = -1;
                for (int i = 0; i < a.size(); i++)
                {
                        int minv = a[i];
                        int same = 0;
                        vector<int> d;
                        for (int j = 0; j < a.size(); j++)
                        {
                                if (a[j] == minv)
                                        same++;
                                else if (a[j] > minv)
                                {
                                        d.push_back(a[j] - minv);
                                }
                        }
                        if (same >= n / 2)
                        {
                                k = INT_MAX;
                                break;
                        }
                        map<int, int> mp;
                        for (auto x : d)
                        {
                                for (auto xx : divide(x))
                                {
                                        mp[xx]++;
                                }
                        }
                        for (auto x : mp)
                        {
                                if (x.second + same >= n / 2)
                                {
                                        k = max(k, x.first);
                                }
                        }
                }
                cout << (k == INT_MAX ? -1 : k) << endl;
        }
        return 0;
}

E. Gardener and Tree

思路分析:
  • 一开始以为暴力能过就写了个暴力然后T了。然后看了下题解,原来是反向的,也就是说我们也是模拟一下删点过程(把这棵树删完),然后统计一下是在第几轮删去的这个点,最后把删去轮数和 k k k比较即可。
代码
#include <bits/stdc++.h>
using namespace std;
const int maxn = 4e5 + 10;
int degree[maxn];
vector<int> e[maxn];
int n, k, ans;
int vis[maxn];
int dis[maxn];
int main()
{
        int t;
        cin >> t;
        while (t--)
        {
                memset(vis, 0, sizeof(vis));
                memset(degree, 0, sizeof(degree));
                memset(dis, 0, sizeof(dis));
                cin >> n >> k;
                ans = n;
                for (int i = 1; i <= n; i++)
                {
                        e[i].clear();
                }
                for (int i = 1; i < n; i++)
                {
                        int u, v;
                        cin >> u >> v;
                        e[u].push_back(v);
                        e[v].push_back(u);
                        degree[u] += 1;
                        degree[v] += 1;
                }
                queue<int> q;
                for (int i = 1; i <= n; i++)
                {
                        if (degree[i] == 1)
                        {
                                q.push(i);
                                vis[i] = 1;
                                dis[i] = 1;
                        }
                }
                while (!q.empty())
                {
                        int x = q.front();
                        q.pop();
                        for (int j = 0; j < e[x].size(); j++)
                        {
                                int u = e[x][j];
                                if (vis[u])
                                        continue;
                                degree[u]--;
                                if (degree[u] == 1)
                                {
                                        q.push(u);
                                        vis[u] = 1;
                                        dis[u] = dis[x] + 1;
                                }
                        }
                }
                int ans = 0;
                for (int i = 1; i <= n; i++)
                {
                        if (dis[i] > k)
                        {
                                ans++;
                        }
                }
                cout << ans << endl;
        }
        return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值