题目描述 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. spark学习(二)

    Spark是一个通用的并行计算框架,由UCBerkeley的AMP实验室开发. Spark和Hadoop有什么不同呢? Spark是基于map reduce算法实现的分布式计算,拥有Hadoop Ma ...

  2. Spring的IoC容器-Spring ApplicationContext容器

    Application Context是spring中较高级的容器.和BeanFactory类似,它可以加载配置文件中定义的bean,将所有的bean集中在一起,当有请求的时候分配bean. 另外,它 ...

  3. [转] sql 删除表数据的drop、truncate和delete用法

    删除表数据的关键字,大家记得最多的可能就是delete.然而,我们做数据库开发,读取数据库数据.对另外的drop.truncate用得就比较少了. 1 drop 出没场合:drop table  ta ...

  4. docker日志输出文件大小设置以及文件个数限制

    问题描述: 今天有同事运行了一个docker容器,不多时就导致宿主机硬盘直接撑爆,消耗了120G,发生的很是突然. 问题排查: 后续查阅资料,发现是因为docker中的某个进程一直在持续输出,而这些输 ...

  5. Building a Radio Listening Station to Decode Digital Audio & Police Dispatches

    On April 7, 2017, residents in Dallas, Texas, woke to the sound of emergency sirens blaring all over ...

  6. Linux常用C函数-接口处理篇(网络通信函数)

    接口处理篇accept,bind,connect,endprotoent,endservent,getsockopt,htonl,htons,inet_addr,inet_aton,inet_ntoa ...

  7. weexpack 的 Login.vue 及 vue 的 Login.vue

    1.登录页 weexpack  Login.vue <!-- 登录页 --> <template> <div class="wrapper"> ...

  8. js跳出循环的方法区别( break, continue, return ) 及 $.each 的(return true 和 return false)

    js编程语法之break语句: break语句会使运行的程序立刻退出包含在最内层的循环或者退出一个switch语句. 由于它是用来退出循环或者switch语句,所以只有当它出现在这些语句时,这种形式的 ...

  9. push代码到github时,每次都要输入用户名和密码的问题

    问题原由 我在Github上 建立了一个小项目TauStreamingServer,可是在每次push代码 的时候,都要求输入用户名和密码,很是麻烦. 如何才能避免每次都输入用户名和密码呢? 解决办法 ...

  10. 【转载】轻松搞懂WebService工作原理

    用更简单的方式给大家谈谈WebService,让你更快更容易理解,希望对初学者有所帮助. WebService是基于网络的.分布式的模块化组件. 我们直接来看WebService的一个简易工作流程: ...