题目描述 Description

佳佳刚进高中,在军训的时候,由于佳佳吃苦耐劳,很快得到了教官的赏识,成为了“小教官”。在军训结束的那天晚上,佳佳被命令组织同学们进行篝火晚会。一共有n个同学,编号从1到n。一开始,同学们按照1,2,……,n的顺序坐成一圈,而实际上每个人都有两个最希望相邻的同学。如何下命令调整同学的次序,形成新的一个圈,使之符合同学们的意愿,成为摆在佳佳面前的一大难题。
佳佳可向同学们下达命令,每一个命令的形式如下:
(b1,b2,...bm-1,bm)
这里m的值是由佳佳决定的,每次命令m的值都可以不同。这个命令的作用是移动编号是b1,b2,…… bm –1,bm的这m个同学的位置。要求b1换到b2的位置上,b2换到b3的位置上,……,要求bm换到b1的位置上。
执行每个命令都需要一些代价。我们假定如果一个命令要移动m个人的位置,那么这个命令的代价就是m。我们需要佳佳用最少的总代价实现同学们的意愿,你能帮助佳佳吗?

输入描述
Input Description

输入第一行是一个整数n(3<=n<=50000),表示一共有n个同学。其后n行每行包括两个不同的正整数,以一个空格隔开,分别表示编号是1的同学最希望相邻的两个同学的编号,编号是2的同学最希望相邻的两个同学的编号,……,编号是n的同学最希望相邻的两个同学的编号。

输出描述
Output Description

这一行只包含一个整数,为最小的总代价。如果无论怎么调整都不能符合每个同学的愿望,则输出-1。

样例输入
Sample Input

4

3 4

4 3

1 2

1 2

样例输出
Sample Output

2

数据范围及提示
Data Size & Hint

【数据规模】

对于30%的数据,n<=1000;

对于全部的数据,n<=50000。

题解

大概是我太弱了吧,每篇题解都一头懵哔emmm

首先这道题题面可以说很难懂了

有n个同学,初始时从1~n坐成一圈。每个同学有两个最想坐在边上的同学。

问能否通过交换部分人的座位满足所有人的需求。若能满足,求交换的最小代价。

其中交换的定义:对于某一次交换,让同学a坐到上次交换结束后b坐的位置上,b坐到上次交换结束后c的位置上......让被涉及到的最后一位同学坐到上次结束后a坐的位置上。

代价的定义:对于每次交换,这次的代价为被涉及到的同学数,总代价为每次交换的代价之和。

首先我们拆环成链。

然后我们可以反过来想:给定一个序列,求交换成1~n的序列的最小代价。

可以想到,其实只需要一次交换就可以解决问题:

设同学a的编号为ca,则把a同学放到ca座位;

然后把之前坐在ca号座位上的同学(设为b)赶到cb座位......

这样每个坐错位置的人,都只会挪一次位置。

所以这种拆链方案的代价=坐错位置的同学数

这样就可以用n方的时间解决问题啦!(撒花

在n方的解法中,我们枚举了断点。对于每个断点,用O(n)的时间再扫一遍。

会炸。

想像两个手链,一个手链从1写到n,另一个手链乱序。

枚举断点,实际上只是把乱序手链的某个珠子对准1号珠拿好,然后把每个珠子看一遍,数不同的珠子数;再把乱序手链的下一个珠子对准1号珠......

如果有一些珠子,它们在第一次数珠子的时候离目标位还有x个珠子,那么下一次离目标就会还有x-1格......

那么它们要么同时对上,要么同时对不上。

于是问题转化成了:

随便拆一下,求此时的 max(dis[]),也就是一次最多对上的珠子数。

答案就是n=max(dis[])的值,也就是最少有多少对不上。

(撒花~

#include<cmath>
#include<cstdio>
#include<cstring>
#include<iostream>
using namespace std;
int f[][],a[],dis[],b[];
bool used[];
int maxd=;
void make(int pos,int x){
maxd=max(pos,maxd);//记录一下排座位到哪了
a[pos]=x;used[x]=;
if(!used[f[x][]]){make(pos+,f[x][]);}
else if(!used[f[x][]]){make(pos+,f[x][]);}
return;
}
int main(){
int n;
scanf("%d",&n);
//造乱序链
//造链的方法很多啦,随便哪种都可以
for(int i=;i<=n;++i){
int x,y;
scanf("%d%d",&x,&y);
if(f[x][]){//如果x的0号朋友位满了
if(f[x][]){cout<<-;return ;}//如果x已经有了两个朋友
f[x][]=i;
}
else f[x][]=i;
if(f[y][]){
if(f[y][]){cout<<-;return ;}
f[y][]=i;
}
else f[y][]=i;
}
make(,);//在1号位放1号同学,然后往下递归
if(maxd!=n){cout<<-;return ;}//如果造不出长为n的链,那不可能只坐一个圈
//
for(int i=;i<=n;++i)
dis[(a[i]-i+n)%n]++;
int ans=;
for(int i=;i<n;++i)
ans=max(ans,dis[i]);
//然后还要像硬币翻面一样翻一下乱序手链
b[]=a[];
for(int i=;i<=n;++i)
b[i]=a[n+-i];
//翻了之后再跑一次
memset(dis,,sizeof(dis));
for(int i=;i<=n;++i)
dis[(b[i]-i+n)%n]++;
for(int i=;i<n;++i)
ans=max(ans,dis[i]);
//
cout<<n-ans;
return ;
}

关于翻面:

如果乱序链为 1 4 3 2 ,对比 1 2 3 4需要代价2

但是如果翻一下就不需要代价了,因为读入中只要坐在一起,但我们强行加了他们坐左边还是右边的要求,所以要反过来再跑一遍。

「NOIP2005」「Codevs1106」篝火晚会的更多相关文章

  1. 【codevs1106】 篝火晚会

    http://codevs.cn/problem/1106/ (题目链接) 题意 将1~n顺序排列的环改成另一个环,问n-不动点数. Solution 啊智障啦,不会做×_× 左转hzwer 代码 / ...

  2. 众安「尊享e生」果真牛的不可一世么?

    近日,具有互联网基因的.亏损大户(成立三年基本没盈利,今年二季度末亏损近4亿,你能指望它多厉害?).财产险公司—众安推出“尊享e生”中高端医疗保险(财险公司经营中高端医疗真的很厉害?真的是中高端医疗险 ...

  3. XCActionBar 「Xcode 中的 Alfred」

    下载地址:https://github.com/pdcgomes/XCActionBar 基本命令: (1)「command+shift+8」或者双击「command」键可以打开「动作输入框窗口」 ( ...

  4. Git 执行 「fork 出来的仓库」和「最新版本的原仓库」内容同步更新

    当我们在 GitHub 上 fork 出一个仓库后,如果原仓库更新了,此时怎样才能保证我们 fork 出来的仓库和原仓库内容一致呢?我们一般关注的是仓库的 master(主干分支)的内容,通过以下步骤 ...

  5. 【翻译】西川善司的「实验做出的游戏图形」「GUILTY GEAR Xrd -SIGN-」中实现的「纯卡通动画的实时3D图形」的秘密,后篇

    http://www.4gamer.net/games/216/G021678/20140714079/     连载第2回的本回,  Arc System Works开发的格斗游戏「GUILTY G ...

  6. 翻译「C++ Rvalue References Explained」C++右值引用详解 Part1:概述

    本文系对「C++ Rvalue References Explained」 该文的翻译,原文作者:Thomas Becker. 该文较详细的解释了C++11右值引用的作用和出现的意义,也同时被Scot ...

  7. 「Windows MFC 」「Edit Control」 控件

    「Windows MFC 」「Edit Control」 控件

  8. 苹果搜索广告后台大揭秘,最全最细致详解,手把手设置教程「后附官方视频」-b

    WWDC2016 搜索广告分会视频和 PPT 发布了,ASO100 带开发者第一时间了解 Search Ads 后台设置(文末有原声视频). 首先介绍一下搜索广告的模式和竞价规则 广告模式为 CPT( ...

  9. 被「李笑来老师」拉黑之「JavaScript微博自动转发的脚本」

    故事的背景如下图,李笑来 老师于10月19日在 知乎Live 开设 一小时建立终生受用的阅读操作系统 的讲座,他老人家看到大家伙报名踊跃,便在微博上发起了一个 猜数量赢取iPhone7 的活动. 因为 ...

随机推荐

  1. js采用concat和sort将N个数组拼接起来的方法

    <script type="text/javascript" > function concatAndSortArray(array1, array2) { if (a ...

  2. PAT (Advanced Level) 1088. Rational Arithmetic (20)

    简单题. 注意:读入的分数可能不是最简的.输出时也需要转换成最简. #include<cstdio> #include<cstring> #include<cmath&g ...

  3. HttpClient配置

    ClientConfiguration.java 该类讲解了HttpClient的各方面的配置 package com.ydd.study.hello.httpclient; import java. ...

  4. LeetCode:926. 将字符串翻转到单调递增

    暴力法超时:思想:动态规划 public int minFlipsMonoIncrb(String S) { int result = S.length(); for (int i = 0; i &l ...

  5. Mybatis详解

    SqlSession(SqlSessionDaoSupport类) SqlSessionDaoSupportSqlSessionDaoSupport是一个抽象的支持类,用来为你提供SqlSession ...

  6. 将文件从已Root Android手机中copy出来的几个cmd窗口命令

    将文件从已Root Android手机中copy出来的几个cmd窗口命令: 以shell身份登录adbadb shell进入adb后切换至root用户su更改文件的所属chown shell *更改文 ...

  7. 临远的spring security教程

    为啥选择Spring Security 欢迎阅读咱们写的Spring Security教程,咱们既不想写一个简单的入门教程,也不想翻译已有的国外教程.咱们这个教程就是建立在咱们自己做的OA的基础上,一 ...

  8. Linux索引节点(Inode:no space for device)用满导致的一次故障

    问题描写叙述 在storm測试环境集群上上nimbus和supervisor自己主动挂调.重新启动时显示no space for device,也不能创建,加入文件及文件夹,df -h查看 ilesy ...

  9. C/C++二进制读写png文件

    以下代码只有最简单的读写.地址定位啥的,个别注释中有.如果要改动png的格式甚么的就要再了解一下png的数据结构如果要十进制的话就跟着注释改一下: /*! * \file CC++二进制读写png文件 ...

  10. poj2482--Stars in Your Window(扫描线)

    题目链接:点击打开链接 链接题目大意:给出n个星星的坐标,每一个星星有一个亮度.给出一个矩形的长和宽,问矩形能包含的星星的最大亮度和(不包含边框). 如果每个星星都是矩形的最左下点.那么每个星星都能够 ...