2021 ICPC 江西省大学生程序设计竞赛 Character Distance

Character Distance(思维、模拟)4星

题意:

给你一个有 n n n个元素的序列,要求选择其中任意至少一个数,使对于这个数在序列中的位置间隔恰好为 m ( 1 ≤ i < j , a i = a j = x , m ≤ j − i ) m(1\leq i< j,a_i=a_j=x,m\leq j-i) m(1i<j,ai=aj=x,mji)且要求序列满足字典序最小,若无法满足输出-1

1 ≤ n , m ≤ 1 0 6 1\leq n,m\leq 10^6 1n,m106

题解:

只需要找到一个数让他满足上述条件即可

  • 当有元素的出现次数为1时,直接输出 s o r t sort sort后的序列即可

  • 其他情况

    p o s pos pos为元素的首位置(排序后), c n t cnt cnt为个数

    • 对于一个元素x,若满足 p o s + ( c n t − 1 ) ∗ m < = m pos+(cnt-1)*m<=m pos+(cnt1)m<=m,则当尽可能选择后面的元素使可以使字典序尽可能小
    • 对于其他情况—— p o s + ( c n t − 1 ) ∗ m > n & & 1 + ( c n t − 1 ) ∗ m ≤ n pos+(cnt-1)*m>n\&\& 1+(cnt-1)*m\leq n pos+(cnt1)m>n&&1+(cnt1)mn时,当第一个 x x x的位置越靠后时字典序越小
    • x x x都不满足上述情况则为输出-1
#include<bits/stdc++.h>
#define endl '\n'
#define x first
#define y second
#define int long long
using namespace std;
typedef long long ll;
typedef pair<int,int>PII;
const int N=1e6+10;
int n,m;
int g[N];
int ans1[N],ans2[N];
map<int,int>mp;
bool check(int ans1[],int ans2[]){
    for(int i=1;i<=n;i++){
        if(ans1[i]>ans2[i]) return false;
        else if(ans1[i]<ans2[i]) return true;
    }
    return true;
}
void solve(){
    cin>>n>>m;
    mp.clear();
    for(int i=1;i<=n;i++){
        cin>>g[i];
        ans1[i]=ans2[i]=0;
        if(!mp.count(g[i])) mp[g[i]]=1;
        else mp[g[i]]++;
    }
    int mi=N;
    sort(g+1,g+1+n);
    for(auto [x,y]:mp){
        if(y==1){
            for(int i=1;i<=n;i++) cout<<g[i]<<' ';
            cout<<endl;
            return ;
        }
    }
    int f1=0,pos1=-1;//第一种情况,从pos往后插
    for(int i=n;i>=1;i--){
        int j=i-1;
        while(g[j]==g[i]&&j>=1) j--;
        i=j+1;
        if(i+(mp[g[i]]-1)*m<=n){
            pos1=g[i],f1=1;
            int cnt=mp[g[i]],t=i;
            while(cnt--){
                ans1[t]=g[i];
                t+=m;
            }
            break;
        }
    }
    if(f1){
        for(int i=1,j=1;i<=n;i++){
            if(g[i]==pos1) continue;
            while(ans1[j]&&j<=n) j++;
            ans1[j++]=g[i];
        }
    }
    int pos2=0,f2=0,cnt=N;//第二种情况,从n往前插
    for(int i=1;i<=n;i++){
        if(i+(mp[g[i]]-1)*m>n&&1+(mp[g[i]]-1)*m<=n){
            if(!f2){
                f2=1;
                cnt=mp[g[i]];
                pos2=g[i];
            }
            else{
                if(cnt>mp[g[i]]){
                    cnt=mp[g[i]];
                    pos2=g[i];
                }
                else if(cnt==mp[g[i]]) pos2=min(pos2,g[i]);
            }
        }
        int j=i+1;
        while(g[i]==g[j]&&j<=n) j++;
        i=j-1;
    }
    if(f2){
        int t=n;
        while(cnt--){
            ans2[t]=pos2;
            t-=m;
        }
        for(int i=1,j=1;i<=n;i++){
            if(g[i]==pos2) continue;
            while(ans2[j]&&j<=n) j++;
            ans2[j++]=g[i];
        }
    }
    if(f1&&!f2){
        for(int i=1;i<=n;i++) cout<<ans1[i]<<' ';
    }
    else if(!f1&&f2){
        for(int i=1;i<=n;i++) cout<<ans2[i]<<' ';
    }
    else if(f1&&f2){
        if(check(ans1,ans2)){
            for(int i=1;i<=n;i++) cout<<ans1[i]<<' ';
        }
        else{
            for(int i=1;i<=n;i++) cout<<ans2[i]<<' ';
        }
    }
    else cout<<-1;
    cout<<endl;
}
signed main(){
    //freopen("in.txt","r",stdin);
	//freopen("ans.txt","w",stdout);
    ios::sync_with_stdio(false);
    cin.tie(0);cout.tie(0);
//    freopen("in.txt","r",stdin);
//    freopen("out.txt","w",stdout);
    int T=1;
    cin>>T;
    while(T--){
        solve();
    }
    return 0;
}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
### 回答1: 2021江西省大学生程序设计竞赛是一项针对大学生的编程竞赛活动。该竞赛旨在提高大学生的编程能力和创新思维,促进计算机科学技术的发展和应用。竞赛内容包括算法设计、程序实现、数据结构等方面,参赛选手需要在规定时间内完成指定的编程任务。这是一项非常有挑战性和有意义的竞赛,对于提高大学生的编程水平和实践能力有很大的帮助。 ### 回答2: 2021年3月14日,江西省大学生程序设计竞赛(ICPC)在江西师范大学举行。本次比赛由江西省计算机学会主办,吉林大学博爱学院赞助,共有15支队伍参赛,此次比赛的主要目的是提高学生们的程序设计算法能力,同时为江西省选出优秀的程序设计人才。 比赛采用ACM国际竞赛的形式,共有12个题目,考察了参赛选手在算法设计、程序实现、数据结构、编程能力等方面的综合素质。比赛时间长达5个小时,选手需要在规定时间内完成尽可能多的题目,并在保证正确性的同时尽量节省时间。 2019年江苏省大学生程序设计竞赛的比赛题分别从算法设计基础、计算几何、动态规划、搜索、数据结构等方面出题,难度适中。所有参赛队伍均在赛场上充分展示了自己的才华和程序设计能力,赛场上紧张的气氛、激烈的角逐使得比赛更加刺激和有趣。 此次比赛从选拔、组织、管理等方面是非常成功的,既展示了江西省大学生程序设计的风采,也为江西省和国家培养了更多的优秀程序设计人才。希望在未来的竞赛中,江西省程序设计的水平能够更上一层楼,培养更多的优秀程序设计人才。 ### 回答3: 2021江西省大学生程序设计竞赛2021年11月7日在南昌大学体育馆举行,来自江西省内的30多所高校的近500支队伍参赛。本次比赛分为省赛和校内赛两个阶段,对参赛队伍进行初步筛选和终极评选。 比赛分为解决8道问题的组成员和4道问题的单人组成员两部分,涵盖了计算几何、动态规划、图论、计算几何等多个领域,难度较高。比赛中,每个队伍有5个小时的时间解决问题,只能在计算机上编写代码解决问题,考验了参赛者的编程实力和团队协作能力。 比赛期间,裁判们在场内设立了各种问题的试题,比如“手工奶酪”、“最大独立集”、“调色板”等,每个问题都要求参赛者在规定时间内精确解决。裁判们在以上操作的基础上,继续引入了随机性、收缩性和对称性等要素,使比赛题目更具挑战性。 本次比赛的成功举办,标志着江西省程序设计竞赛赛事的正式起航,并为江西省内高校的程序设计爱好者提供了一个互相交流、共同提高的平台。同时,也为将来江西省大学生程序设计竞赛的举办打下了坚实的基础。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值