[NOIP2005][CODEVS1106]篝火晚会(模拟+数学相关)
来源:互联网 发布:知乎 hiv携带者 编辑:程序博客网 时间:2024/04/28 02:59
题目描述
传送门
题解
首先知道从初状态转移到末状态和从末状态转移到初状态是一样的,那么我们可以构造出末状态,然后计算转移到初状态的最小代价。
可以知道转移的代价一定为不在应该在的位置上的人的数量,那么就要使最多的人在位置上。考虑到环的情况,我们假设对于一个数i的目标是将它放到i这个位置,那么如果有若干个数距离各自的目标需要移动的步数相等的话,说明令其中的一个数在位置上,那么其他的数也在位置上。假设这些数是一个组,找出有最多人数的那个组,那么ans=n-组内人数。
注意没有规定是顺时针还是逆时针,所以要正反做两次。
代码
#include<iostream>#include<cstring>#include<cstdio>#include<queue>using namespace std;const int max_n=5e4+5;int n,L,R,t,ans;int a[max_n],b[max_n],l[max_n],r[max_n],pre[max_n],nxt[max_n];bool flag,vis[max_n];int cnt1[max_n],cnt2[max_n];queue <int> q;int main(){ scanf("%d",&n); for (int i=1;i<=n;++i) scanf("%d%d",&l[i],&r[i]); for (int i=2;i<=n;++i) pre[i]=i-1; pre[1]=n; for (int i=1;i<n;++i) nxt[i]=i+1; nxt[n]=1; flag=true; vis[1]=vis[pre[1]]=vis[nxt[1]]=true; a[1]=1; a[pre[1]]=l[1]; a[nxt[1]]=r[1]; while (!q.empty()) q.pop(); q.push(pre[1]); q.push(nxt[1]); while (!q.empty()) { int now=q.front(); q.pop(); L=l[a[now]]; R=r[a[now]]; if (!vis[pre[now]]&&vis[nxt[now]]) { if (a[nxt[now]]==L) { a[pre[now]]=R; vis[pre[now]]=true; q.push(pre[now]); } else if (a[nxt[now]]==R) { a[pre[now]]=L; vis[pre[now]]=true; q.push(pre[now]); } else { flag=false; break; } } else if (vis[pre[now]]&!vis[nxt[now]]) { if (a[pre[now]]==L) { a[nxt[now]]=R; vis[nxt[now]]=true; q.push(nxt[now]); } else if (a[pre[now]]==R) { a[nxt[now]]=L; vis[nxt[now]]=true; q.push(nxt[now]); } else { flag=false; break; } } else if (vis[pre[now]]&&vis[nxt[now]]) { if (a[pre[now]]==L) { if (a[nxt[now]]!=R) { flag=false; break; } } else if (a[nxt[now]]==L) { if (a[pre[now]]!=R) { flag=false; break; } } else { flag=false; break; } } } if (!flag) { printf("-1\n"); return 0; } for (int i=1;i<=n;++i) { t=(a[i]-i+n)%n; cnt1[t]++; ans=max(ans,cnt1[t]); t=(a[n-i+1]-i+n)%n; cnt2[t]++; ans=max(ans,cnt2[t]); } printf("%d\n",n-ans);}
0 0
- [NOIP2005][CODEVS1106]篝火晚会(模拟+数学相关)
- [codevs1106][NOIP2005]篝火晚会
- noip2005 篝火晚会 (模拟)
- 【模拟】篝火晚会(noip2005)
- NOIP2005 篝火晚会
- NOIP2005篝火晚会
- NOIP2005 篝火晚会
- noip2005篝火晚会 2008.10.18
- 洛谷 P1053 [NOIP2005 T3] 篝火晚会
- UESTC1723 篝火晚会(组合数学)
- wikioi1106 篝火晚会 置换模拟
- 篝火晚会(脑洞题)
- Vijos P1008 篝火晚会(组合数学,置换群)
- 【NOIP2005提高组T3】篝火晚会-置换群
- 洛谷1053 篝火晚会-------数论+模拟
- 贪心模拟-洛谷P1053 篝火晚会
- code vs 1106 篝火晚会(置换)
- noip2005提高组篝火晚会 && nyoj59题小明活动的组织任务
- 关于python的self
- python后端开发视频教程学习笔记
- hibernate实现双向一对多的映射
- 周易六十四卦——大畜卦
- caffe学习笔记(7):get the deploy.prototxt
- [NOIP2005][CODEVS1106]篝火晚会(模拟+数学相关)
- C++实验6—矩阵求和
- hdu 5690 多种方法实现
- 3dmax入门教程(二) 视图配置的常用设置
- java的一些不同于其它语言的特点
- HDU 5242Game 树上的贪心 树形dp 求出使K条链的权值总和最大
- 【codevs 1106】篝火晚会 (2005年NOIP全国联赛提高组)(置换群)
- 数组随机访问计算方法
- Sqlite demo 和总结