2023-2024 ICPC Arranging Adapters

Arranging Adapters

题目

You take your laptop out and try to plug it in when you notice that the only socket is already in use. Your friends smirk and reply: “No socket for you, no training for us”. Their smirks quickly fade as you pull out a power strip, unplug the charger from the socket, and plug it back into the power strip. Now, there is enough space for your charger as well.

Figure A.1: Illustration of Sample Input 2. The first six chargers can be plugged in as shown. Note that this is not the only possible solution. However, it can be shown that it is impossible to plug in all seven chargers.

However, as soon as more sockets are available, your friends suddenly take out more devices that need to be charged. You realize that you will not get them to train like this, so you decide to trick them into solving a problem instead.

Your power strip comprises a row of s s s sockets, and each socket is 3  cm 3\ \text{cm} 3 cm in diameter. Furthermore, as you examine the chargers, you notice that they all have integer lengths. The plug of each charger is always on one of the two ends, and each charger can only be used in two orientations. Chargers cannot overlap, but can touch, and can extend beyond the end of the power strip as long as they are plugged in to a socket. Now you challenge them to charge as many devices as possible. This is visualized in Figure A.1. Hoping that this allows them to avoid the training, your friends agree to write a program to solve this.

Input

The input consists of:

  • One line with two integers n n n and s s s ( 1 ≤ n ≤ 2 ⋅ 1 0 5 (1\leq n\leq2\cdot 10^5 (1n2105, 1 ≤ s ≤ 1 0 9 ) 1\leq s\leq10^9) 1s109), the number of chargers you have and the number of sockets on the power strip.
  • One line with n n n integers w w w ( 3 ≤ w ≤ 1 0 9 3\leq w\leq10^9 3w109), the width of each charger in centimetres.

Note that you are allowed to rotate chargers by 18 0 ∘ 180^\circ 180 before plugging them in.

Output

Output the maximum number of chargers you can plug into the power strip at the same time.

Examples

case 1:

Input
5 7
7 4 4 5 8
Output
5

case 2:

Input
8 9
7 4 3 6 4 8 5 6
Output
6

题目翻译

n n n个插座孔,每个孔 3 cm,“插板” m m m厘米,接下来m个数字,每个 a i a_i ai代表每个插头多长,插的位置是在插头在边上,不能在中间,可以180°反转

做法

首先我们我们先排两边的,因为两边可以 插头朝外,所以无论插头多长,都各只要 1个,对吧。

然后就是里面的部分,我们先排序,因为一定是先插入小的插头,这个没有问题对吧,

然后用map<int,int> mp记录 %3 后的个数mp[ar[i]%3]++,因为 长度为4 和长度为 5的两个插头 一个多出来的是1,一个多出来的是2,刚好拼凑在一起,同时,我们发现两个4cm的也能拼凑在一起,各多出来的1cm往中间,

A A A A O B B B B
1 2 3 4 5 6 7 8 9

下面的是厘米,上面的是两个4cm的摆放,刚好中间多出来1cm,占用 9 3 = 3 \frac93 = 3 39=3个插座

所以多出来的1cm总共占用(mp[1] + 1) / 2因为如果多多出来的1cm也要占用一个插座,
多出来的2cm总共占用mp[2]个,因为2cm只能和1cm配对,所以在记录1cm和2cm的时候,能配对就配对,因为这样能最少减少2cm占用的个数

//cin >> n >> m;
int num = 0, ans = 0;//两边的在最后计算
    for (int i = 1; i <= n - 1; i++)
    {
        if (i == n - 1)//到n - 1的时候,说明n - 2个全插满了,最后两个要算入两边朝外的
        {
            ans = n - 2;
            break;
        }
        int x = ar[i] / 3;//记录不多出来的时候 占用几个
        int y = ar[i] % 3;
        mp[y]++;
        if (mp[1] && mp[2])
        {
            int mins = min(mp[1], mp[2]);
            x += mins;//能配对了就拿出来
            mp[1] -= mins;
            mp[2] -= mins;
        }
        if (num + x + (mp[1] + 1) / 2 + mp[2] > m)
        {
            ans = i - 1;//第i个插入不了,就i-1个呗
            break;
        }
        num += x;
    }

    cout << ans + 2 << endl;

因为输入可以输入1 ,2 这样,可以直接特判就完了

代码

#include <bits/stdc++.h>
#define int long long
using namespace std;
#define endl '\n'
const int N = 200005;
int n;
int ar[N];
map<int, int> mp;
void solve()
{
    int n, m;
    cin >> n >> m;
    for (int i = 1; i <= n; i++)
    {
        cin >> ar[i];
    }
    if (m == 1 && n >= 1)
    {
        cout << 1 << endl;
        return;
    }
    if (m >= 2 && n <= 2)
    {
        cout << n << endl;
        return;
    }
    sort(ar + 1, ar + 1 + n);

    m -= 2;
    int num = 0, ans = 0;
    for (int i = 1; i <= n - 1; i++)
    {
        if (i == n - 1)
        {
            ans = n - 2;
            break;
        }
        int x = ar[i] / 3;
        int y = ar[i] % 3;
        mp[y]++;
        if (mp[1] && mp[2])
        {
            int mins = min(mp[1], mp[2]);
            x += mins;
            mp[1] -= mins;
            mp[2] -= mins;
        }
        if (num + x + (mp[1] + 1) / 2 + mp[2] > m)
        {
            ans = i - 1;
            break;
        }
        num += x;
    }

    cout << ans + 2 << endl;
}
signed main()
{

    solve();

    return 0;
}
  • 31
    点赞
  • 26
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值