noi2009变换序列
noi2009变换序列
一、题目
对于N个整数0,1,…,N-1,一个变换序列T可以将i变成Ti,其中:Ti∈{0,1,…,N-1}且Ui=1 to n-1 {Ti}={0,1,…,N-1}。任意x,y∈{0,1,…,N-1},定义x和y之间的距离D(x,y)=min{|x-y|,N-|x-y|}。给定每个i和Ti之间的距离D(i,Ti),你需要求出一个满足要求的变换序列T。如果有多个满足条件的序列,输出其中字典序最小的一个。
说明:对于两个变换序列S和T,如果存在p<N,满足:对于i=0,1,…,p-1,Si=Ti且Sp<Tp,我们称S比T字典序小。
输入文件中的第一行为一个整数N,表示序列的长度。
接下来的一行为N个整数Di,其中:Di表示i和Ti之间的距离。
如果至少存在一个满足要求的变换序列T,则输出一行为N个整数,表示你计算得到的字典序最小的T;否则输出“No Answer”(不含引号)。
输出文件中相邻两个数字之间用一个空格分开,行末不包含多余空格。
5
1 1 2 2 1
1 2 4 0 3
对于30%的数据,满足:N<=50;
对于60%的数据,满足:N<=500;
对于100%的数据,满足:N<=10000。
分类标签 Tags 点此展开
二、分析
1、题目描述:
我现在简要述说一下这一题的意思:题目的意思就是给出x对y的对应关系:,现在给出D(x,y)和x,求y,并且要求字典序最小的y。(x这组数是从0到n-1,y这组数属于0到n-1)
下面分析一下样例就更加方便理解这个题目了:
|
X |
0 |
1 |
2 |
3 |
4 |
|
D(x,y) |
1 |
1 |
2 |
2 |
1 |
|
Y |
1 |
2 |
4 |
0 |
3 |
表一
样例输入中给了n为5,,所以表一第一行x的值也是从0到4。表一的第二行D(x,y)就是输入数据的x,y的关系。最后需要我们求的就是表一第三行的y的数据。
我们可以看到上表中的(每列)每组x,y,D(x,y)都是满足关系,比如x=0,D(x,y)=1,y=1这一列,
|x-y|=1,N-|x-y|=4,故D(x,y)=1,所以关系成立,后面的以此类推。
2、题目思考:
我们在仔细来看一下关系式,发现对于这样的一个关系式,我们知道D(x,y)和x,求y的话,y最多有四个值,不过其实仔细拿实例出来分析之后,就发现这四个值是可以变成两个值的。
看到题目,发现题目是一个赤裸裸的二分匹配。这个题目可以用匈牙利算法来做,匈牙利算法的时间复杂度是O(nm),在这里是完全ok的。
这个题目还有另外一个难点,就是要求字典序最小的y,其实求最小的y可以在寻找交错路(匹配关系)的时候倒序寻找,不过这样做的时候要注意,在存边关系的连接表的时候要注意从小往大存,确保从字典序小的边找起。
因为如果正序查找,按照匈牙利算法的算法规则,那么一定是找到的字典序最大的那个。
问题:求二分图最大匹配可以用最大流(Maximal Flow)或者匈牙利算法(Hungarian Algorithm)
3、总结:
总结:其实这个题目就是二分匹配中的匈牙利算法,套用下匈牙利的模板,再想好怎么输出字典序最小的y就ok了。
三、代码
#include<iostream>
#include<iomanip>
#include<cstdio>
#include<cmath>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<queue>
#include<map>
#define MAXN 10010
using namespace std; int graph[MAXN][];//每个点最多连出2条边,存边时保证graph[i][0] int vis[MAXN];//表示节点是否被访问
int match[MAXN];//Y集合中的点i与X集合的match[i]匹配
int ans[MAXN];//用于输出结果
int n; //用来构建关系,确保字典序小的存在前面
void addedge(int i,int ver)
{
if(graph[i][]<)
{
graph[i][]=ver;
return;
}
else if(graph[i][]>ver)
{
graph[i][]=graph[i][];
graph[i][]=ver;
}
else graph[i][]=ver;
}
//匈牙利算法中的寻找交错路
bool crosspath(int ns)
{
int j,nt;
for(j=;j<=;j++)//每个点优先匹配编号较小的点(graph[i][0]
{
nt=graph[ns][j]; if(nt<) continue;
if(vis[nt]) continue;
vis[nt]=;
if(match[nt]<||crosspath(match[nt]))
{
match[nt]=ns;
return true;
}
}
return false;
}
//匈牙利算法倒叙从每个点找交错路,确保求出最小字典序y
int find()
{
memset(match,,sizeof(match));
memset(vis,,sizeof(vis));
int i,tot=;
for(i=n-;i>=;i--)//倒叙从每个点找交错路
{
if(crosspath(i)) tot++;
memset(vis,,sizeof(vis));
}
return tot;
} int main()
{
//freopen("in.txt","r",stdin);
//输入数据以及确定每个D(x,y)和x对应的y,用于构造二分图
int i,qh,l,r;
scanf("%d",&n);
memset(graph,,sizeof(graph));
for(i=;i<n;i++)
{
scanf("%d",&qh);//qh为读入的d[i],从i向i+d[i],i-d[i]连边(要取模)
l=((i-qh)%n+n)%n;
r=((i+qh)%n+n)%n;
addedge(i,l);
if(r!=l) addedge(i,r);
}
if(find()<n)//未能完全匹配则无解。
{
printf("No Answer");
exit();
}
//统计答案输出。
for(int i=;i<n;i++) ans[match[i]]=i;
printf("%d",ans[]);
for(int i=;i<n;i++) printf(" %d",ans[i]);
return ;
}
noi2009变换序列的更多相关文章
- Bzoj 1562: [NOI2009]变换序列 匈牙利算法,二分图匹配
题目: http://cojs.tk/cogs/problem/problem.php?pid=409 409. [NOI2009]变换序列 ★★☆ 输入文件:transform.in 输出文 ...
- BZOJ 1562 [NOI2009] 变换序列
[NOI2009] 变换序列 [题解] 就是有一个序列,每个位置可以填两个数,不可重复,问最小字典序. 显然,可以建一个二分图,判合法就是找完美匹配. 那怎么弄最小字典序呢?有好多种解法,我这里给出了 ...
- [Luogu 1963] NOI2009 变换序列
[Luogu 1963] NOI2009 变换序列 先%Dalao's Blog 什么?二分图匹配?这个确定可以建图? 「没有建不成图的图论题,只有你想不出的建模方法.」 建图相当玄学,不过理解大约也 ...
- Luogu P1963 [NOI2009]变换序列(二分图匹配)
P1963 [NOI2009]变换序列 题意 题目描述 对于\(N\)个整数\(0,1, \cdots ,N-1\),一个变换序列\(T\)可以将\(i\)变成\(T_i\),其中\(T_i \in ...
- 【bzoj1562】 NOI2009—变换序列
http://www.lydsy.com/JudgeOnline/problem.php?id=1562 (题目链接) 题意 给出一个序列(0~n-1),这个序列经过某个变换会成为另外一个序列,但是其 ...
- bzoj1562[NOI2009]变换序列——2016——3——12
任意门:http://www.lydsy.com/JudgeOnline/problem.php?id=1562 题目: 对于0,1,…,N-1的N个整数,给定一个距离序列D0,D1,…,DN-1,定 ...
- P1963 [NOI2009]变换序列
对于\(N\)个整数\(0, 1, \cdots, N-1,\)一个变换序列\(T\)可以将\(i\)变成\(T_i\),其中 \(T_i \in \{ 0,1,\cdots, N-1\}\)且 \( ...
- 【BZOJ1562】【jzyzOJ1730】【COGS409】NOI2009变换序列 二分图匹配
[问题描述] 对于N个整数0, 1, ……, N-1,一个变换序列T可以将i变成Ti,其中 定义x和y之间的距离.给定每个i和Ti之间的距离D(i,Ti), 你需要求出一个满足要求的变换 ...
- BZOJ1562: [NOI2009]变换序列(二分图 匈牙利)
Description Input Output Sample Input 5 1 1 2 2 1 Sample Output 1 2 4 0 3 HINT 30%的数据中N≤50:60%的数据中N≤ ...
随机推荐
- 【题解】BZOJ3489 A Hard RMQ problem(主席树套主席树)
[题解]A simple RMQ problem 占坑,免得咕咕咕了,争取在2h内写出代码 upd:由于博主太菜而且硬是要用指针写两个主席树,所以延后2hQAQ upd:由于博主太菜而且太懒所以他决定 ...
- 【25】session练习
#用登录练习session html1为首页,html2为登录页面 def session1(request): uname=request.session.get('myname','请登录') # ...
- MySQL中数据中设计中的范式与反范式
设计关系数据库时,遵从不同的规范要求,设计出合理的关系型数据库,这些不同的规范要求被称为不同的范式,各种范式呈递次规范,越高的范式数据库冗余越小.但是有些时候一昧的追求范式减少冗余,反而会降低数据读写 ...
- swift笔记——环境搭建及Hello,Swift!
版权声明:本文为博主原创文章,未经博主同意不得转载. https://blog.csdn.net/enson16855/article/details/29829601 首先要下载XCode6,仅仅有 ...
- 0405-服务注册与发现-客户端负载均衡-Ribbon 同Eureka使用,Ribbon脱离Eureka使用
一.Ribbon 同Eureka使用,注意事项 前几节一同使用,注意事项: 如果没有其他区域数据源,则根据客户端配置进行猜测(与实例配置相反).能够获取eureka.client.availabili ...
- 玩转type类型(牛逼克拉斯 )
一.前言 一说起type()方法肯定有很多人都知道这不就是查看某个对象类型的嘛,其实不然,他还有更牛逼的应用------创建类 >>> type(1) <class 'int' ...
- 剑指offer 面试58题
面试58题: 题目:翻转字符串 题:牛客最近来了一个新员工Fish,每天早晨总是会拿着一本英文杂志,写些句子在本子上.同事Cat对Fish写的内容颇感兴趣,有一天他向Fish借来翻看,但却读不懂它的意 ...
- tcpdump Demo
tcpdump Demo lxw ~$ tcpdump -i eth0 tcpdump: eth0: You don't have permission to capture on that devi ...
- 对称加密&非对称加密
对称密钥密码算法的特点: 算法简单,加/解密速度快,但密钥管理复杂,不便于数字签名: 非对称密钥密码算法的特点: 算法复杂,加/解密速度慢,密钥管理简单,可用于数字签名. 所以将两者结合起来,形成混合 ...
- 在像Angular2这样的SPA应用中使用Google Analytics的方法
Angular2のようなシングルページアプリケーションでGoogleアナリティクスを使う方法 如何在像Angular2这样的SPA应用中使用Google Analytics? 试着调查了一下. 由于S ...