小红的排列构造(dp优化)

简介: 小红的排列构造(dp优化)

题目描述

小红拿到了一个长度为n的数组a,她希望你构造两个排列p和q,满足对于i∈[1,n],ai∈[1,n]pi或qi二选一。你能帮帮她吗?定义排列是一个长度为n的数组,其中1到n每个元素恰好出现1次。

输入描述:第一行输入一个正整数n,代表两个数组的长度。 第二行输入n个正整数ai。1≤n≤10^5,1≤ai≤n。

输出描述:如果无解,请输出-1。 否则第一行输出n个正整数pi,第二行输出n个正整数qi,代表小红构造的两个排列。有多解时输出任意即可。

输入

3

2 3 2

输出

2 3 1

1 3 2

输入

4

1 1 1 1

输出:-1

#include<bits/stdc++.h>
#include<iostream>
#include<vector>
using namespace std;
const long long N=1e7+5;
inline int read(){//内联函数效率更高
    int x=0,f=1;
    char c=getchar();
    while(c<'0'||c>'9')
    {
        if(c=='-')
            f=-1;
        c=getchar();
    }
    while(c>='0'&&c<='9'){
        x=(x<<1)+(x<<3)+(c^48),c=getchar();
    }
    return x*f;
}
inline void print(int x)
{
    if(x<0)
        putchar('-'),x=-x;
    if(x>9)
        print(x/10);
    putchar(x%10+'0');
    return;}
int n,k=0,z=0;
vector<int> tr(N),arr(N),p1(N),p2(N);//向量比数组更加灵活与方便
int main(){
  cin>>n;
  for(int i=1;i<=n;i++){
    arr[i]=read();
    if(tr[arr[i]]==2){
      cout<<"-1";
      return 0;
    }
        ++tr[arr[i]];
  }
  for(int i=1;i<=n;i++){
    if(tr[arr[i]]==1){
      p1[i]=arr[i];
            p2[i]=arr[i];
    }
    if(tr[arr[i]]==3){
      while(tr[++k]!=0);
        p1[i]=k;
      p2[i]=arr[i];
    }
    if(tr[arr[i]]==2){
      tr[arr[i]]=3;
      p1[i]=arr[i];
      while(tr[++z]!=0);
        p2[i]=z;
    }
  } 
  for(int i=1;i<=n;i++)print(p1[i]),putchar(32);
  putchar(10);
  for(int i=1;i<=n;i++)print(p2[i]),putchar(32);
  putchar(10);  
    return 0;
}

这个虽然通过运行但是时间和内存都耗费很大

#include<bits/stdc++.h>
#define ll long long
const ll N=1e5+5;
#define _for(i,a,b) for(int(i)=(a);(i)<(b);(i)++)
using namespace std;
inline int read(){
    int x=0,f=1;
    char ch=getchar();
    while(ch<'0'||ch>'9')
    {
        if(ch=='-')f=-1;ch=getchar();
    }
    while(ch>='0'&&ch<='9'){
        x=(x<<1)+(x<<3)+(ch^48),ch=getchar();
    }
    return x*f;
}
void write(int x)
{
    if(x<0)putchar('-'),x=-x;
    if(x>9) write(x/10);
    putchar(x%10+'0');
    return;}
int n,k=0,z=0;
vector<int> tr(N),arr(N),p1(N),p2(N);
int main(){
  cin>>n;
  for(int i=1;i<=n;i++){
    arr[i]=read();
    if(tr[arr[i]]==2){
      cout<<"-1";
      return 0;
    }
        ++tr[arr[i]];
  }
  for(int i=1;i<=n;i++){
    if(tr[arr[i]]==1){
      p1[i]=arr[i];
            p2[i]=arr[i];
    }
    if(tr[arr[i]]==3){
      while(tr[++k]!=0);
        p1[i]=k;
      p2[i]=arr[i];
    }
    if(tr[arr[i]]==2){
      tr[arr[i]]=3;
      p1[i]=arr[i];
      while(tr[++z]!=0);
        p2[i]=z;
    }
  } 
  for(int i=1;i<=n;i++)write(p1[i]),putchar(32);
  putchar(10);
  for(int i=1;i<=n;i++)write(p2[i]),putchar(32);
  putchar(10);    
    return 0;
}

原因如下:

第一次定义的数组范围过大,造成无用空间过多的浪费;

#define _for(i,a,b) for(int(i)=(a);(i)<(b);(i)++)类似于定义了一个模板,效率更高。

  • n 用于存储整数的数量;
  • kz 用于临时存储新的整数值;
  • tr 数组记录每个整数出现的次数;
  • arr 数组存储原始整数序列;
  • p1p2 数组分别存储变换后的两个序列;
  • 读取整数序列,统计每个整数出现的次数并存储在tr数组中;
  • 遍历arr数组,根据tr[arr[i]]的值决定如何填充p1p2
  • 如果某个整数出现了4次,先将其置为3次,然后分别将它放入p1和一个新的未出现过的整数放入p2
  • 如果某个整数出现了偶数次但不是4次,将其中一个放入p1,然后找一个未出现过的整数放入p2
  • 如果某个整数出现了奇数次,直接放入两个新数组;
  • 最后输出处理后的两个序列


目录
相关文章
|
6月前
|
存储 安全 JavaScript
如何使用Set的delete()方法删除元素?
如何使用Set的delete()方法删除元素?
523 122
|
5月前
|
机器学习/深度学习 存储 并行计算
大模型推理显存优化系列(3):FlowMLA——面向高吞吐的DP MLA零冗余显存优化
本文将介绍蚂蚁集团ASystem团队在推理显存优化上的新工作FlowMLA
|
算法 C++ 容器
【C++11算法】iota算法
【C++11算法】iota算法
740 0
|
SQL 关系型数据库 MySQL
Navicat使用HTTP通道连接MySQL(远程mysql3306端口关闭或者只允许localhost链接状态)...
Navicat使用HTTP通道连接MySQL(远程mysql3306端口关闭或者只允许localhost链接状态)...
6661 0
Navicat使用HTTP通道连接MySQL(远程mysql3306端口关闭或者只允许localhost链接状态)...
|
12月前
|
SQL 程序员 Linux
推荐几个不错的数据库设计工具
推荐几个不错的数据库设计工具
992 11
|
12月前
|
存储 设计模式 算法
【23种设计模式·全精解析 | 行为型模式篇】11种行为型模式的结构概述、案例实现、优缺点、扩展对比、使用场景、源码解析
行为型模式用于描述程序在运行时复杂的流程控制,即描述多个类或对象之间怎样相互协作共同完成单个对象都无法单独完成的任务,它涉及算法与对象间职责的分配。行为型模式分为类行为模式和对象行为模式,前者采用继承机制来在类间分派行为,后者采用组合或聚合在对象间分配行为。由于组合关系或聚合关系比继承关系耦合度低,满足“合成复用原则”,所以对象行为模式比类行为模式具有更大的灵活性。 行为型模式分为: • 模板方法模式 • 策略模式 • 命令模式 • 职责链模式 • 状态模式 • 观察者模式 • 中介者模式 • 迭代器模式 • 访问者模式 • 备忘录模式 • 解释器模式
【23种设计模式·全精解析 | 行为型模式篇】11种行为型模式的结构概述、案例实现、优缺点、扩展对比、使用场景、源码解析
|
算法 数据可视化 调度
数学建模——农村公交与异构无人机协同配送优化
数学建模——农村公交与异构无人机协同配送优化
6821 3
|
Java 应用服务中间件
SpringBoot获取项目文件的绝对路径和相对路径
SpringBoot获取项目文件的绝对路径和相对路径
698 1
SpringBoot获取项目文件的绝对路径和相对路径
|
Ubuntu Linux 网络安全
在Linux中,能否给⼀个网卡配置多个IP? 如果能,怎么配置?
在Linux中,能否给⼀个网卡配置多个IP? 如果能,怎么配置?
|
关系型数据库 MySQL 数据库连接
解决 mysql8.0 ERROR 1045 (28000): Access denied for user ‘ODBC‘@‘localhost‘ (using password: NO)用户访问拒绝
解决 mysql8.0 ERROR 1045 (28000): Access denied for user ‘ODBC‘@‘localhost‘ (using password: NO)用户访问拒绝
6847 52
解决 mysql8.0 ERROR 1045 (28000): Access denied for user ‘ODBC‘@‘localhost‘ (using password: NO)用户访问拒绝