Make a Permutation! CodeForces - 864D 解题报告

这道题的思路并不难,贪心+模拟,每次把没出现的往前排就可以,但是当时比赛时这道题反复WA了很多次,就是没过,比赛完看别人的代码,才发现自己忽略了一个限制条件,那就是重复数有多个,且含有最大的值得情况(QAQ),每次都离AC差了那么点,唉

题目链接

下面给出WA的代码,以示警戒:

#include <bits/stdc++.h>

using namespace std;
typedef long long ll;
const int maxn=2e5+10;
int used[maxn],t[maxn],s[maxn];
bool ok[maxn];

int main()
{
    int n;  scanf("%d",&n);

    memset(used,0,sizeof(used));
    memset(ok,0,sizeof(ok));
    for(int i=1;i<=n;i++)
    {
        int a; scanf("%d",&a);
        t[i]=a; used[a]++;
    }

    priority_queue<int ,vector<int>,greater<int> > que;
    for(int i=1;i<=n;i++)
        if(!used[i])  que.push(i);
    for(int i=1;i<=n;i++)
    {
        if(used[t[i]]>1&&(que.top()<t[i]||(que.top()>=t[i]&&ok[t[i]]==true)))
        {
            s[i]=que.top();
            que.pop();
        }
        else
        {
            s[i]=t[i];
            if(used[t[i]]>1) ok[t[i]]=true;
        }
    }

    int cnt=0;
    for(int i=1;i<=n;i++)
    {
        if(t[i]!=s[i]) cnt++;
    }

    printf("%d\n",cnt);
    for(int i=1;i<=n;i++)
    {
        if(i-1) printf(" ");
        printf("%d",s[i]);
    }
    return 0;
}

再给出AC代码:

#include <bits/stdc++.h>

using namespace std;
typedef long long ll;
const int maxn=2e5+10;
int used[maxn],t[maxn],s[maxn];
bool ok[maxn];

int main()
{
    int n;  scanf("%d",&n);

    memset(used,0,sizeof(used));
    memset(ok,0,sizeof(ok));
    for(int i=1;i<=n;i++)
    {
        int a; scanf("%d",&a);
        t[i]=a; used[a]++;
    }

    priority_queue<int ,vector<int>,greater<int> > que;
    for(int i=1;i<=n;i++)
        if(!used[i])  que.push(i);
    for(int i=1;i<=n;i++)
    {
        if(used[t[i]]>1&&(que.top()<t[i]||(que.top()>=t[i]&&ok[t[i]]==true)))
        {
            used[t[i]]--;
            s[i]=que.top();
            que.pop();
            used[s[i]]++;
        }
        else
        {
            s[i]=t[i];
            if(used[t[i]]>1) ok[t[i]]=true;
        }
    }

    int cnt=0;
    for(int i=1;i<=n;i++)
    {
        if(t[i]!=s[i]) cnt++;
    }

    printf("%d\n",cnt);
    for(int i=1;i<=n;i++)
    {
        if(i-1) printf(" ");
        printf("%d",s[i]);
    }
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值