zoukankan      html  css  js  c++  java
  • POJ_1455_Crazy tea party_解题思路

    题目来源:http://poj.org/problem?id=1455

     题目意译:
    有n个人围在桌子前面喝茶,等大家都坐定后,必然有个前后左右顺序,比如:a左边b,b左边c,依次类推,最后一个假设是g,那么他左边必然是a。

    形成一个圆环。

    现在有个规则,规定每次只能相邻两个人进行交换位置。

    请问要经过多少次交换,才能让之前位置交换(b左边a,c左边b,a左边是g)

    思路:

    大家都清楚假定是一排的情况下:

    a b c d e f g

    如果位置交换后:

    g f e d c b a

    需要经过n*(n-1)/2次交换(冒泡法进行交换)

    现在情况是环形,试问能不能将环拆分成两个线性,然后进行交换,再拼接在一起。

    举例如下:

    a b c d e f g(g后面又是a)

    如果分成a b c,d e f g两部分,分别进行逆序,然后连接,是不是满足条件呢?

    交换后c b a, g f e d

    连接后为:c b a g f e d,在环路中,其实位置更改后为g f e d c b a,是满足条件的。

    那么题目得解:

    现在问题是假定环形的长度是N,如果进行截图,才能使得交换次数是最少的呢?
    假定N的环形,分成一个长度为k,另一个长度是N-k的线段。

    那么需要交换的次数为:

    k*(k-1)/2

    (N-k)*(N-k-1)/2

    相加后就是需要交换的总次数。

    题目要求交换次数最少。

    那么就是求 

    k*(k-1)/2+
    (N-k)*(N-k-1)/2的最小值。

    很容易根据公式,二次函数在极值时取N/2的时候。

    所以题目对应程序如下:

     1 #include <stdio.h>
     2 #include <stdlib.h>
     3 int main()
     4 {
     5     int n,s;
     6     int pre,sufix;
     7     scanf("%d",&n);
     8     while(n--)
     9     {
    10         scanf("%d",&s);
    11         pre=(s>>1);
    12         sufix=s-pre;
    13         printf("%d\n",(pre*(pre-1)+sufix*(sufix-1))/2);
    14     }
    15     //system("pause");
    16 }
  • 相关阅读:
    正则表达式 1
    14 同步 1
    14 线程属性
    14 线程状态
    14 线程
    window.location.hostname与 window.location.host 区别
    泛型 的通配符类型 extends super
    svn拷贝一个项目作为新项目
    List Collections sort
    && 和 || 逻辑运算符
  • 原文地址:https://www.cnblogs.com/weisteve/p/2214265.html
Copyright © 2011-2022 走看看