题目链接:http://codeforces.com/problemset/problem/814/B

题目意思:分别给定一个长度为 n 的不相同序列 a 和 b。这两个序列至少有 i 个位置(1 ≤ i ≤ ), a[i] != b[i] 。现在需要构造一个长度为 n,每个数只能取值1~n 且只能取值一次的序列 p, 使得恰好存在有一个位置 i(1 ≤ i ≤ ), ai ≠ p。和恰好存在一个位置 j (1 ≤ j ≤ n) , bj ≠ pj  ,保证这个序列 p 有n-1个位置是跟序列a和b的数是相同的。如果有多个符合的序列,输出任意一个即可。

  【 中文解说起来怎么感觉有点啰哩吧嗦的 = = (大家还是看不明白意思且自问英文还过得去的,建议直接看英文意思)】

题目解析:首先,p序列取值范围1~n(这个我有看到),但只能取值一次,这个貌似真的没有说,看到后台测试样例才发现。这个有点坑。

  然后我们不难想到先构造一条保存 a[i] = b[i](p[i]=a[i]), a[j] != b[j] (p[j] = 0,代表未知) 的 p 序列。

  接着可以发现题目说, a 和 b 有 i 个位置的数是不相同的。其实,这个 i 只能为 1 (test3)或者 2(这个情况比较多)。

  分析 i = 1 这种情况,只可能 a != b, 所以填入一个不等于 a 和 b 的数就可以了(前提要有一个 vis 数组标记,所以没有 vis 过的就是该填的数了)

  分析 i = 2 这种情况,假设 a 序列对应 a1、a2,  b 序列对应b1、b2, p在这两个位置分别取值p1、p2

  (1)a1=a2,b1=b2, a1!=b1    ——》 p1=a1, p2=b1 或者 p1=b1,p2=a2

  (2)a1=a2!=b1,b1!=b2  或者   a1!= a2 , b1=b2!=a1

  (3)a1 != a2 != b1 != b2

  情况(2)、(3),p的取值需要根据当前a1、a2,b1、b2,是否vis过来取。当序列a和b相同位置且值相同,就标记访问过。这样当遇到 (2)(3)情况,取值就取没有 vis 过的。

  当然我们还需要进行一次预处理。为啥?

  先看 test37这个例子。因为是先处理第三个位置的,但是a[3] 和 b[3] 都都没有vis过, 如果很不幸的取了b[3]=1,而不是 a[3]=3, 之后第四个位置就无值可取了(都vis过)。然后这种思路解题就不适合了。

5
5 4 3 5 2
5 4 1 1 2

  所以这个预处理就是保存a[i] = b[i] (1 ≤ i ≤ )时,vis[a[i]] =1之后,当遇到 a[j] != b[j] 时(1 ≤ j ≤ n),但有可能 a[j] 或者 b[j] 是 vis 过的,此时也要打标记。这个先后出现顺序是没所谓的,大家想想就明白了。

  构造题还是挺考思维的,而且想问题得全面点呢~~~

 #include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <algorithm>
using namespace std; const int maxn = + ;
int a[maxn], b[maxn];
int p[maxn];
int vis[maxn];
int n; void Output()
{
for (int i = ; i <= n; i++) {
printf("%d%c", p[i], i != n ? ' ': '\n');
}
} int main()
{
#ifndef ONLINE_JUDGE
freopen("in1.txt", "r", stdin);
#endif // ONLINE_JUDGE while (scanf("%d", &n) !=EOF) {
for (int i = ; i <= n; i++) {
scanf("%d", &a[i]);
p[i] = vis[i] = ;
} int cntzero = , pos = ;
for (int i = ; i <= n; i++) {
scanf("%d", &b[i]);
if (b[i] == a[i]) {
p[i] = b[i];
vis[b[i]] = ;
}
else { //b[i] != a[i]
if (vis[b[i]] && !vis[a[i]]) {
p[i] = a[i];
vis[a[i]] = ;
}
else if (!vis[b[i]] && vis[a[i]]) {
p[i] = b[i];
vis[b[i]] = ;
}
cntzero++;
pos = i;
}
} if (cntzero == && b[pos] != a[pos]) {
for (int j = ; j <= n; j++) {
if (!vis[j]) {
p[pos] = j;
break;
}
}
}
// cntzero = 2
else {
for (int i = ; i <= n; i++) {
if (p[i] == ) {
if (!vis[a[i]] && vis[b[i]]) {
p[i] = a[i];
vis[p[i]] = ;
}
// vis[a[i]] && !vis[b[i]] 或者 !vis[a[i]] && !vis[b[i]]
else {
p[i] = b[i];
vis[p[i]] = ;
}
}
}
}
Output();
}
return ;
}

 

codeforces 814B.An express train to reveries 解题报告的更多相关文章

  1. Codeforces - 814B - An express train to reveries - 构造

    http://codeforces.com/problemset/problem/814/B 构造题烦死人,一开始我还记录一大堆信息来构造p数列,其实因为s数列只有两项相等,也正好缺了一项,那就把两种 ...

  2. An express train to reveries

    An express train to reveries time limit per test 1 second memory limit per test 256 megabytes input  ...

  3. B. An express train to reveries

    B. An express train to reveries time limit per test 1 second memory limit per test 256 megabytes inp ...

  4. Codeforces Round #418 (Div. 2) B. An express train to reveries

    time limit per test 1 second memory limit per test 256 megabytes input standard input output standar ...

  5. #418 Div2 Problem B An express train to reveries (构造 || 全排列序列特性)

    题目链接:http://codeforces.com/contest/814/problem/B 题意 : 有一个给出两个含有 n 个数的序列 a 和 b, 这两个序列和(1~n)的其中一个全排列序列 ...

  6. CF814B An express train to reveries

    思路: 模拟,枚举. 实现: #include <iostream> using namespace std; ; int a[N], b[N], cnt[N], n, x, y; int ...

  7. codeforces 558B. Amr and The Large Array 解题报告

    题目链接:http://codeforces.com/problemset/problem/558/B 题目意思:给出一个序列,然后找出出现次数最多,但区间占用长度最短的区间左右值. 由于是边读入边比 ...

  8. codeforces 515B. Drazil and His Happy Friends 解题报告

    题目链接:http://codeforces.com/problemset/problem/515/B 题目意思:有 n 个 boy 和 m 个 girl,有 b 个 boy 和 g 个 girl ( ...

  9. codeforces 514B. Han Solo and Lazer Gun 解题报告

    题目链接:http://codeforces.com/problemset/problem/514/B 题目意思:给出双头枪的位置(x0, y0),以及 n 个突击队成员的坐标.双头枪射击一次,可以把 ...

随机推荐

  1. js处理事件冒泡

    给Dom元素添加事件时,有时候会遇到事件冒泡,处理方法如下: $("#Tab1 .close").live("click", function (event) ...

  2. 修改hosts文件不起作用

    今天遇到个很奇怪的问题,在hosts文件里添加了一些域名指向后,发现根本没起作用,后来还发现个细节,就是hosts文件左下角有个小锁的标志,开始以为是杀毒软件之类的把他锁了.可是没找到在哪里有相关操作 ...

  3. Type Java compiler level does not match the version of the installed Java project facet.项目内容没错但是项目上报错,不影响运行

    1.Window->Show View->Problems 2.在项目上右键properties->project Facets->修改右侧的version  保持一致 3.w ...

  4. 安装MySQL版本为mysql-installer-community-5.7.17.msi

    双击MySQL安装包, 勾选复选框,点击下一步: 选择仅仅服务器模式,点击下一步: 直接点击执行: 执行完成,点击下一步: 确认配置,点击下一步: 输入用户名和密码,点击下一步: 默认选项,点击下一步 ...

  5. Android_Kotlin 代码学习

    https://github.com/ldm520/Android_Kotlin_Demo

  6. 爬虫任务一:使用httpclient去爬取百度新闻首页的新闻标题和url,编码是utf-8

    第一个入手的爬虫小任务: maven工程 <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi=" ...

  7. C#数组的笔记

    Array.Copy的笔记: 1.将值类型的元素装箱位引用类型的元素,比如讲一个Int32[]的元素复制到Object[]中 2.将引用类型的元素拆箱为值类型的元素 3.加宽CLR基元值类型,比如讲一 ...

  8. [转]C#读写远程共享文件夹

    1.在服务器设置一个共享文件夹,在这里我的服务器ip地址是10.200.8.73,共享文件夹名字是share,访问权限,用户名是administrator,密码是11111111. 2.新建一个控制台 ...

  9. python16_day07【Socket网络编程】

    一.简介 1.理解C/S,B/S 2.IOS七层模型(http://www.cnblogs.com/linhaifeng/articles/5937962.html) 二.什么是Socket 我们看看 ...

  10. 从零到一创建ionic移动app:应用anjularjs编写ionic项目

    推荐两篇文章,带你入门 ionic中文项目(作为了解ionic基础结构用):http://blog.csdn.net/i348018533/article/details/47258449/ ioni ...