补题:C. Paprika and Permutation

C. Paprika and Permutation

传送门:Problem - 1617C - Codeforces

题意:

思路:

首先这个题要知道这个结论:

当 x > a[i] 时,a[i] mod x == a[i]

当 x <= a[i] 时,0 <= a[i] % x < ( a[i] +1 ) / 2

当 a[i] <= n  && a[i] 在[1, n] 中只出现一次时,不用操作

当 a[i] > n || a[i] 在[ 1 , n ] 中出现超过两次,操作

1. 数组排序

2. 从小到大枚举每个数,若需要操作,这个数字只能变成 < ( a[i] + 1 ) / 2的任何数字

AC代码:

#include<bits/stdc++.h>
using namespace std;
#define int long long
const int N = 1e5 + 10;
int vis[N];
void solve()
{
    memset( vis , 0 , sizeof vis );
    int n; cin >> n;
    vector<int> a(n + 1);
    for( int i = 1 ; i <= n ; i++ )
    {
        cin >> a[i]; 
        if( a[i] <= n )vis[a[i]] = 1;
    }
    int p = 1; int sum = 0;
    sort( a.begin() + 1 , a.end() );
    for( int i = 1 ; i <= n ; i++)
    {
        if( a[i] <= n && a[i] != a[i-1] )continue;
        while( vis[p] )p++;
        if( p >= ( a[i] + 1 ) / 2 )
        {
            puts("-1"); return;
        }
        vis[p] = 1; sum++;
    }
    cout << sum << endl;
}
signed main()
{
    int tt; cin >> tt;
    while(tt--)solve();
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值