AcWing:第56场周赛

AcWing:第56场周赛

4482. 分组 - AcWing题库

给定一个长度为 n 的数组 a1,a2,…,an。

请你将这 n 个元素重新分组,要求每个组内的元素两两不等,且分组数量应尽可能少。

请你计算最少所需的分组数量。

例如,给定一个数组 a=[1,2,4,3,3,2],我们至少需要将所有元素分为两组,一种可行分组方案为:[1,2,3] 和 [2,3,4]。

输入格式

第一行包含一个整数 n。

第二行包含 n 个整数 a1,a2,…,an。

输出格式

一个整数,表示最少所需的分组数量。

数据范围

前三个测试点满足 1≤n≤10。
所有测试点满足 1≤n≤100,1≤ai≤100。

输入样例1:
6
1 2 4 3 3 2
输出样例1:
2

问题解析

想象一下,我们要把n个相同的东西分开放,那么显然是需要n个盒子,这样才能保证一个盒子里只有一个相同的东西。

这题直接统计出现最多的那个数的次数就行,次数为多少,就要分多少组。

AC代码

#include<iostream>
using namespace std;
#include<vector>
#include<algorithm>
#include<math.h>
#include<set>
#include<numeric>
#include<string>
#include<string.h>
#include<iterator>
#include<map>
#include<unordered_map>
#include<stack>
#include<list>
#include<queue>
#include<iomanip>

#define endl '\n'
#define int ll
typedef long long ll;
typedef unsigned long long ull;
typedef pair<ll, ll>PII;
const int N = 2e5 + 50;

signed main()
{
    ios_base::sync_with_stdio(false);
    cin.tie(nullptr);
    cout.tie(nullptr);
    int n,res=0;
    unordered_map<int, int>mymap;
    cin >> n;
    vector<int>v(n);
    for (int i = 0; i < n; i++)
    {
        cin >> v[i];
        mymap[v[i]]++;
        res = max(res, mymap[v[i]]);
    }
    cout << res;
    return 0;
}

4483. 格斗场 - AcWing题库

一个格斗场内有 n 个战士,其中第 i 个战士的战斗力为 ai。

作为格斗场内的经理人,你需要给战士们安排一对一的决斗。

这些决斗是一场接一场进行的,一场结束后才会安排下一场。

为了保证决斗的观赏性,在安排时需保证:

  • 决斗双方的战斗力不能相同。
  • 决斗双方的战斗力差距不能超过 K。

已知,在决斗中战斗力高的选手一定可以将战斗力低的选手击败,并且失败的选手会被赶出格斗场。

请你合理安排决斗,使得当剩余选手之间无法再安排任何决斗时,剩余选手的数量越少越好。

请你输出剩余选手的最小可能数量。

输入格式

第一行包含两个整数 n,K。

第二行包含 n 个整数 a1,a2,…,an。

输出格式

一个整数,表示剩余选手的最小可能数量。

数据范围

前四个测试点满足 1≤n≤10。
所有测试点满足 1≤n≤2×105,1≤K≤106,1≤ai≤10^6。

输入样例1:
7 1
101 53 42 102 101 55 54
输出样例1:
3

问题描述

看一个数能不能活下来,只要看数组里有没有和大于它且不超过k的数,如果有,那这个数显然可以被排除掉,如果没有,那这个数就能留到最后面。

可以对数组升序排序,从最小的数开始找起,如果有大于它,且差值不超过k的数,这个数就被排掉,我们去找下一个,如果没有,那这个数可以留到最后,用一个变量记录下来。

AC代码

#include<iostream>
using namespace std;
#include<vector>
#include<algorithm>
#include<math.h>
#include<set>
#include<numeric>
#include<string>
#include<string.h>
#include<iterator>
#include<map>
#include<unordered_map>
#include<stack>
#include<list>
#include<queue>
#include<iomanip>

#define endl '\n'
#define int ll
typedef long long ll;
typedef unsigned long long ull;
typedef pair<ll, ll>PII;
const int N = 2e5 + 50;

signed main()
{
    ios_base::sync_with_stdio(false);
    cin.tie(nullptr);
    cout.tie(nullptr);
    priority_queue<int, vector<int>, greater<>>que;
    int n, res = 0, mn = -1, ans = 0, k;
    cin >> n >> k;
    vector<int>v(n);
    for (int i = 0; i < n; i++)
    {
        cin >> v[i];
        que.push(v[i]);
    }
    while (!que.empty())
    {
        ans = 1;
        mn = que.top();
        que.pop();
        while (!que.empty() && que.top() == mn)
        {
            que.pop();
            ans++;
        }
        if (que.empty() || que.top() - mn > k)
        {
            res += ans;
        }
    }
    cout << res;
    return 0;
}

4484. 有限小数 - AcWing题库

给定三个整数 p,q,b,请你计算十进制表示下的 p/q 的结果在 b 进制下是否为有限小数。

输入格式

第一行包含整数 T,表示共有 T 组测试数据。

每组数据占一行,包含三个整数 p,q,b。

输出格式

每组数据输出一行结果,如果 p/q 的结果在 b进制下是有限小数,则输出 YES,否则输出 NO

数据范围

前五个测试点满足 1≤T≤10。
所有测试点满足 1≤T≤105,0≤p≤1018,1≤q≤1018,2≤b≤1018。

输入样例1:
2
6 12 10
4 3 10
输出样例1:
YES
NO

问题解析

首先讲一下小数转化成b进制的形式:假设有个小数是0.abcd,要转成x进制,那就是**(a*x^-1 )+(b *x^-2 )+(c *x^-3)+(d *x^ -4)**。

如果我们给十进制下的小数乘上一个x,那就会变成:**(a )+(b *x^-1 )+(c x^-2)+(d x^ -3)

那么对于一个k位小数,我们只要乘上k个x,就可以把这个小数全部转化成整数。

也就是说:对于p/q,只要(p/q) * x^k 是整数,就说明p/q的小数可以用k个有限小数表示出来。

(具体看注释)

AC代码

#include<iostream>
using namespace std;
#include<vector>
#include<algorithm>
#include<math.h>
#include<set>
#include<numeric>
#include<string>
#include<string.h>
#include<iterator>
#include<map>
#include<unordered_map>
#include<stack>
#include<list>
#include<queue>
#include<iomanip>

#define endl '\n'
#define int ll
typedef long long ll;
typedef unsigned long long ull;
typedef pair<ll, ll>PII;
const int N = 2e5 + 50;

ll gcd(ll a, ll b)
{
    return a == 0 ? b : gcd(b % a, a);
}

signed main()
{
    ios_base::sync_with_stdio(false);
    cin.tie(nullptr);
    cout.tie(nullptr);
    int t;
    cin >> t;
    while (t--)
    {
        ll p, q, b;
        cin >> p >> q >> b;
        //(p/q)*b^k要想是整数,b^k * p就要整除q,我们可以直接把p和q约分,这样就不用管p了,直接看q和b就行
        q /= gcd(p, q);
        while (q > 1)
        {
            ll x = gcd(q, b);
            //如果q和b的公约数互质,说明他俩无法继续约分了,结束程序
            if (x == 1)break;
            while (q % x == 0)q /= x;
        }
        //如果q能和k个b约分约到1,就说明q能整除b^k ,反之不行
        if (q > 1)cout << "NO" << endl;
        else cout << "YES" << endl;
    }
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值