zoukankan      html  css  js  c++  java
  • [NOIP2005] 提高组 洛谷P1053 篝火晚会

    题目描述

    佳佳刚进高中,在军训的时候,由于佳佳吃苦耐劳,很快得到了教官的赏识,成为了“小教官”。在军训结束的那天晚上,佳佳被命令组织同学们进行篝火晚会。一共有n个同学,编号从1到n。一开始,同学们按照1,2,……,n的顺序坐成一圈,而实际上每个人都有两个最希望相邻的同学。如何下命令调整同学的次序,形成新的一个圈,使之符合同学们的意愿,成为摆在佳佳面前的一大难题。

    佳佳可向同学们下达命令,每一个命令的形式如下:

    (b1, b2,... bm -1, bm)

    这里m的值是由佳佳决定的,每次命令m的值都可以不同。这个命令的作用是移动编号是b1,b2,…… bm的这m个同学的位置。要求b1换到b2的位置上,b2换到b3的位置上,……,要求bm换到b1的位置上。执行每个命令都需要一些代价。我们假定如果一个命令要移动m个人的位置,那么这个命令的代价就是m。我们需要佳佳用最少的总代价实现同学们的意愿,你能帮助佳佳吗?

    输入输出格式

    输入格式:

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

    输出格式:

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

    输入输出样例

    输入样例#1:
    4
    
    3 4
    
    4 3
    
    1 2
    
    1 2
    
    输出样例#1:
    2

    说明

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

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

    2005提高组第三题

    在新的环中,如果a和b的相对位置没有变(即a相对于原位置左移了x个位置,b也相对于原位置左移了x个位置,向右同理),那么可以考虑:如果不移动两人,只移动其他人,最优解是多少?

    显然,如果在移动时,相对移动了x位的人最多,那么这种情况下,等同于需要移动的人越少。

    需要移动的人数=总人数-不需要移动的人数。 (题中佳佳要求别人交换的顺序可以任意指定,所以在可行的情况下,让m个人归位只需要m代价)

    具体处理方法见代码

     1 /*by SilverN*/
     2 #include<algorithm>
     3 #include<iostream>
     4 #include<cstring>
     5 #include<cstdio>
     6 #include<cmath>
     7 #include<vector>
     8 using namespace std;
     9 const int mxn=50010;
    10 int read(){
    11     int x=0,f=1;char ch=getchar();
    12     while(ch<'0' || ch>'9'){if(ch=='-')f=-1;ch=getchar();}
    13     while(ch>='0' && ch<='9'){x=x*10+ch-'0';ch=getchar();}
    14     return x*f;
    15 }
    16 int w[mxn][2];
    17 int c1[mxn],c2[mxn],r[mxn];
    18 int vis[mxn];
    19 int n;
    20 int main(){
    21     n=read();
    22     int i,j;
    23     for(i=1;i<=n;i++) w[i][0]=read(),w[i][1]=read();
    24     r[1]=1;r[2]=w[1][0];
    25     vis[r[1]]=vis[r[2]]=1;
    26     for(i=2;i<n;i++){
    27         if(r[i-1]==w[r[i]][0])r[i+1]=w[r[i]][1];
    28         else if(r[i-1]==w[r[i]][1])r[i+1]=w[r[i]][0];
    29             else{printf("-1
    ");return 0;}
    30         vis[r[i+1]]=1;
    31     }
    32     for(i=1;i<=n;i++)if(!vis[i]){
    33         printf("-1
    ");
    34         return 0;
    35     }
    36     for(i=1;i<=n;i++){
    37         c1[(r[i]-i+n)%n]++;//正序 
    38         c2[(r[n-i+1]-i+n)%n]++;//逆序 
    39         //WA 1: n-i+1写在了c2的外面 
    40     }
    41     int ans=0;
    42     for(i=1;i<=n;i++){
    43         ans=max(ans,c1[i]);
    44         ans=max(ans,c2[i]);
    45     }
    46     printf("%d
    ",n-ans);
    47     return 0;
    48 }
  • 相关阅读:
    问题 A: 【递归入门】全排列
    第一个struct2程序(2)
    第一个struct2程序
    Java学习 第二节
    重学Java
    Servlet过滤器
    struct2
    Java web struct入门基础知识
    one by one 项目 part 6
    软件工程导论 桩模块和驱动模块
  • 原文地址:https://www.cnblogs.com/SilverNebula/p/6004815.html
Copyright © 2011-2022 走看看