codeforces B. Fixed Points 解题报告
题目链接:http://codeforces.com/problemset/problem/347/B
题目意思:给出一个包含n个数的排列a,在排列a中最多只能作一次交换,使得ai = i 这样的匹配达到最多。
作一次交换,最理想的情况是,在原来匹配好的序列中再匹配到两个数;最坏的情况是,即使作怎样的交换,都不可能再找到可以匹配的两个数,也就是说,根本不需要作交换。至于一般情况下,是可以再匹配到一个数的。
我是设了两个数组(分别有n个数):a(用来存储待判断的序列a)和b(依次存储0~n-1个数)。然后判断a[i] 与b[i]是否相等,这是为了确定未作交换前两组序列本来能够匹配的数目;如果不符合就尝试交叉比较: a[i] = b[a[i]] 和 b[i] = a[b[a[i]]] 是否满足。若同时满足,代表做完一次交换可以达到最大的匹配,也就是匹配到2个。如果只满足其中一条,那么交换后可以达到一般的情况:匹配到一个数。否则,将会是最坏的情况,这时,干脆不要做交换。
举个例子:假设 a 序列为:0 1 2 6 7 5 3 1
b 序列为:0 1 2 3 4 5 6 7
第一次遇到的不匹配的数是 a[3], 由于考虑到b[i]存储数据的特殊性(依次存储0~n-1个数),因此通过 a[i] = b[a[i]] 的判断,a[3] = b[a[3]](b[6] = 6)和 b[3] = a[b[a[3]]] (a[b[6]] = a[6] = 3) , 发现两条式子都符合,那么可以达到最大的匹配。
还有一个非常值得注意的细节,序列a存储的数有可能比n-1要大(假设n = 8,a[i]有可能是9(0 <= i <= n-1),所以要先判断。
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
using namespace std; const int maxn = + ;
int a[maxn], b[maxn]; int main()
{
int i, n, cnt, flag, flag1; // flag用来标记达到最大的匹配数(2个),flag1标记一般情况交换后的匹配(1个)
while (scanf("%d", &n) != EOF)
{
for (i = ; i < n; i++)
{
scanf("%d", &a[i]);
b[i] = i;
}
flag = flag1 = ;
for (cnt = i = ; i < n; i++)
{
if (a[i] == b[i]) // 统计未交换前的匹配数
cnt++;
else if (a[i] <= b[a[i]]) // a[i]有可能比n-1大
{
if (b[i] == a[b[a[i]]] && a[i] == b[a[i]])
flag = ; // 序列中至少存在一对通过交换后,在原来的基础上再匹配多2个数
else
flag1 = ; // 交换一次,可以在原来匹配的基础上匹配多1个数
} }
if (flag)
printf("%d\n", cnt+);
else if (flag1) // 注意不能跟flag一起做判断条件,条件语句写成flag && flag1是错误的,这样写应归纳到到一个if的判断里
printf("%d\n", cnt+);
else
printf("%d\n", cnt); // 怎样交换都不能再找到匹配,干脆一次都不交换
}
return ;
}
codeforces B. Fixed Points 解题报告的更多相关文章
- Codeforces Round 665 赛后解题报告(暂A-D)
Codeforces Round 665 赛后解题报告 A. Distance and Axis 我们设 \(B\) 点 坐标为 \(x(x\leq n)\).由题意我们知道 \[\mid(n-x)- ...
- Codeforces Round 662 赛后解题报告(A-E2)
Codeforces Round 662 赛后解题报告 梦幻开局到1400+的悲惨故事 A. Rainbow Dash, Fluttershy and Chess Coloring 这个题很简单,我们 ...
- Codeforces Round #277.5 解题报告
又熬夜刷了cf,今天比正常多一题.比赛还没完但我知道F过不了了,一个半小时贡献给F还是没过--应该也没人Hack.写写解题报告吧= =. 解题报告例如以下: A题:选择排序直接搞,由于不要求最优交换次 ...
- codeforces B.Fixed Points
link:http://codeforces.com/contest/347/problem/B 很简单,最多只能交换一次,也就是说,最多会增加两个.可能会增加一个.也可能一个也不增加(此时都是fix ...
- codeforces B. Simple Molecules 解题报告
题目链接:http://codeforces.com/problemset/problem/344/B 题目意思:这句话是解题的关键: The number of bonds of an atom i ...
- codeforces 591A. Wizards' Duel 解题报告
题目链接:http://codeforces.com/problemset/problem/591/A 题目意思:其实看下面这幅图就知道题意了,就是Harry 和 He-Who-Must-Not-Be ...
- codeforces 582A. GCD Table 解题报告
题目链接:http://codeforces.com/problemset/problem/582/A 网上很多题解,就不说了,直接贴代码= = 官方题解: http://codeforces.com ...
- codeforces 581C. Developing Skills 解题报告
题目链接:http://codeforces.com/problemset/problem/581/C 题目意思:给出 n 个数:a1, a2, ..., an (0 ≤ ai ≤ 100).给出值 ...
- codeforces 577B. Modulo Sum 解题报告
题目链接:http://codeforces.com/problemset/problem/577/B 题目意思:就是给出 n 个数(a1, a2, ..., an) 和 m,问能不能从这 n 个数中 ...
随机推荐
- Java 编辑tips
1. windows 安装 jdk配置环境 1) 下载jdk,正常安装结束,保存安装路径. 2)我的电脑—〉右键属性—〉高级系统设置—〉环境变量—〉添加系统变量 新建两个变量 JAVAHOM ...
- 配置hibernate
http://blog.csdn.net/hanjiancanxue_liu/article/details/9966423
- hihocoder1187 Divisors
传送门 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 Given an integer n, for all integers not larger than n, f ...
- Linux下J2EE环境搭建
1.下载MyEclipse 2010的linux安装包. myeclipse-10.1-offline-installer-linux 2.将下载MyEclipse 2010的linux安装包,使用X ...
- ActivityInfo taskAffinity
通常在Manifest里面使用 <application android:icon="@drawable/icon" android:label="@string/ ...
- log4j使用教程详解(怎么使用log4j2)
1. 去官方下载log4j 2,导入jar包,基本上你只需要导入下面两个jar包就可以了(xx是乱七八糟的版本号): log4j-core-xx.jar log4j-api-xx.jar 2. 导入到 ...
- c/s架构nginx+php-fpm通信原理
FastCGI是一个运用于Http Server和动态脚本语言间通信的接口,多数流行的Http Server都支持FastCGI,包括Apache.Nginx和lighttpd等.同时,Fas ...
- seajs之seajs-debug坑
最近遇到两个关于seajs-debug的坑 一个与preload有关,详情见https://github.com/seajs/seajs-debug/issues/15 一个与map时间戳有关,详情见 ...
- Json数据
<title>无标题文档</title>//使用 jquery 必须的先加载 <script src="jquery-2.1.1.min.js"> ...
- Ultra-QuickSort
Ultra-QuickSort Time Limit: 7000MS Memory Limit: 65536K Total Submissions: 44489 Accepted: 16176 ...