当前位置: 首页 > news >正文

AtCoder真题及详细题解 ABC425B: Find Permutation 2

AtCoder真题及详细题解 ABC425B: Find Permutation 2

题目描述

给定一个长度为 NNN 的整数序列 A=(A1,A2,…,AN)A=(A_1,A_2,\ldots,A_N)A=(A1,A2,,AN)。其中,AAA 的每个元素要么是 −1-11,要么是 111NNN(包括 111NNN)之间的整数。

判断是否存在一个长度为 NNN 的整数序列 P=(P1,P2,…,PN)P=(P_1,P_2,\ldots,P_N)P=(P1,P2,,PN),满足以下所有条件,并在存在时给出任意一个 PPP

  • PPP111NNN 的一个排列。
  • 对于所有 i=1,2,…,Ni=1,2,\ldots,Ni=1,2,,N,如果 Ai≠−1A_i\neq -1Ai=1,则 Pi=AiP_i=A_iPi=Ai
输入格式

输入从标准输入读取,格式如下:

NNN A1A_1A1 A2A_2A2 …\ldots ANA_NAN

输出格式

如果不存在满足条件的 PPP,输出 No

否则,输出 Yes P1P2…PNP_1~P_2~\ldots~P_NP1 P2  PN,其中 PPP 满足所有条件。

如果有多个满足条件的 PPP,输出其中任意一个。

输入输出样例 1
输入 1
4
-1 -1 2 -1
输出 1
Yes
3 1 2 4
输入输出样例 #2
输入 2
5
-1 -1 1 -1 1
输出 #2
No
输入输出样例 3
输入 3
7
3 -1 4 -1 5 -1 2
输出 3
Yes
3 7 4 1 5 6 2
说明/提示
样例解释 1

P=(3,1,2,4)P=(3,1,2,4)P=(3,1,2,4) 满足所有条件。

除此之外,P=(1,3,2,4)P=(1,3,2,4)P=(1,3,2,4)P=(4,3,2,1)P=(4,3,2,1)P=(4,3,2,1) 也满足所有条件。

样例解释 2

不存在满足所有条件的 PPP

数据范围
  • 1≤N≤101\le N\le 101N10
  • Ai=−1A_i=-1Ai=11≤Ai≤N1\le A_i \le N1AiN
  • 所有输入值均为整数。

AC代码

#include <bits/stdc++.h>
using namespace std;int n;
int a[20], p[20];      // a存储输入序列,p存储当前尝试的排列
bool used[20];         // 标记数字是否已被使用// 深度优先搜索函数,尝试构建排列
// pos: 当前正在处理的位置
bool dfs(int pos) {// 如果已经处理完所有位置,返回成功if (pos == n + 1) return true;// 如果当前位置有固定值if (a[pos] != -1) {int val = a[pos];// 如果该值未被使用if (!used[val]) {p[pos] = val;           // 将固定值放入排列used[val] = true;       // 标记该值已使用// 递归处理下一个位置if (dfs(pos + 1)) return true;used[val] = false;      // 回溯:取消标记}return false;  // 如果固定值已被使用,返回失败} // 如果当前位置没有固定值,尝试所有可能的值else {for (int val = 1; val <= n; val++) {// 如果该值未被使用if (!used[val]) {p[pos] = val;       // 尝试将该值放入排列used[val] = true;   // 标记该值已使用// 递归处理下一个位置if (dfs(pos + 1)) return true;used[val] = false;  // 回溯:取消标记}}return false;  // 所有可能值都尝试过但都不成功,返回失败}
}int main() {cin >> n;// 读取输入并初步检查重复for (int i = 1; i <= n; i++) {cin >> a[i];if (a[i] != -1) {// 如果固定值重复出现,直接输出"No"if (used[a[i]]) {cout << "No" << endl;return 0;}used[a[i]] = true;  // 标记固定值已使用}}// 重置used数组,准备深度优先搜索// 注意:这里重置了数组,但前面已经检查过固定值重复,所以是安全的memset(used, false, sizeof(used));// 使用深度优先搜索尝试构建排列if (dfs(1)) {// 如果找到解,输出结果cout << "Yes" << endl;for (int i = 1; i <= n; i++) {cout << p[i] << " ";}cout << endl;} else {// 如果找不到解,输出"No"cout << "No" << endl;}return 0;
}

功能分析

核心算法
  • 深度优先搜索(DFS): 使用回溯法尝试构建满足条件的排列
  • 回溯法: 当某条路径无法继续时,撤销当前选择,尝试其他可能性
主要步骤
  1. 输入处理与初步检查

    • 读取序列长度n和序列A
    • 检查固定值是否有重复,如有重复直接输出"No"
  2. DFS构建排列

    • 从位置1开始递归处理每个位置
    • 对于有固定值的位置:直接使用该值(如果可用)
    • 对于无固定值的位置:尝试所有未使用的数字
    • 使用used数组记录哪些数字已被使用
  3. 输出结果

    • 找到解:输出"Yes"和排列P
    • 无解:输出"No"
时间复杂度
  • 最坏情况:O(n!),但由于n≤10,在可接受范围内
  • 实际运行:通过剪枝和提前终止,通常远好于最坏情况

文末福利:《csp信奥赛12大高频考点专题集训》

https://edu.csdn.net/course/detail/40437 点击跳转到秘籍
在这里插入图片描述

更多csp信奥赛c++完整系列课程,点击查看老师的个人主页:
https://edu.csdn.net/lecturer/7901 点击链接

在这里插入图片描述

#include<bits/stdc++.h>
using namespace std; 
int main(){cout<<"############# 祝看到这篇秘籍的OIer: ###############";cout<<"#### AC不是偶然,一等奖是必然!祝你AK全场! ########";cout<<"############# 复赛夺魁,一等在手! #################";return 0;
}
http://www.dtcms.com/a/541155.html

相关文章:

  • 电子机箱网站建设报告上海百度做网站
  • web渗透知识总结
  • 盲盒小程序系统开发:助力品牌拓展新市场
  • Llama-2-7b 昇腾部署:六大场景性能基准核心指标拆解
  • Vue3.x核心技术与实战(八)
  • 批量吞吐量实测:Llama-2-7b 昇腾 NPU 六大场景数据报告
  • 网站建设涉及的法律易名中国域名门户网站
  • 企业网站托管的方案软件开发流程详细
  • 做推广适合哪些网站深圳办公室设计公司排名
  • 做网站设计怎么提升自己怎么搭建个人博客网站
  • 测试题-4
  • 莱西大型网站建设做宣传海报的网站
  • Coze套餐实现工作总结
  • 做新网站的swot分析怎样选择网站建设
  • Mantle Global Hackathon 2025:里程碑升级后的首场生态猎星行动!
  • 景观建设网站宁波网站推广多少钱一个
  • Spring JDBC高级操作全解析
  • Matlab混合编程技术学习教程——目录
  • 基于MATLAB的LBFGS优化算法实现
  • 【matlab】字符串数组 转 double
  • 技术速递|Playwright MCP 调试 Web 应用时,GitHub Copilot 生成断言脚本的实用方法
  • RTSP低延迟播放重构:SmartMediaKit如何让系统“看见即行动”
  • 技术文档搭建实战:基于PandaWiki的五步自动化方案
  • wordpress能做手机站么电商网站设计系列
  • 深入剖析SLAB分配器原理与优化实战
  • 建设安全备案登入那个网站wordpress文章微信公众号推送
  • 6.1.3.1 大数据方法论与实践指南-开源大数据离线调度平台
  • 技术支持 东莞网站建设石材seo智能优化系统
  • 南沙区建设局网站如何进行网站域名解析
  • GNSS+LiDAR+Camera(双目)+IMU(战术级)的多传感器融合定位-WayFinder