CH-Round-#63-OrzCC杯#2省选热身赛

题目一

描述

exchange

背景
有n个人一同出去玩,每个人有一张火车票。由于火车票实行实名制,每张火车票也对应一个人。
描述
由于某种原因,现在出现了以下情况:每个人手中有一张票,这张票可能是自己的也可能是别人的。现在任意两个人之间可以交换手中的票,求最少进行多少次交换使得每个人都拿到自己的票。假定交换是依次进行的,即同一时刻只进行一次交换,我们也想知道,第一步有多少种方案,能保证交换次数最少。
输入格式
输入有2行,第一行有两个用空格隔开的正整数n、k(k代表任务种类,详见输出格式),第二行有n个用空格隔开的正整数,第i个为Pi,代表着第i个人手中的票是第Pi个人的。
输出格式
如果k=1,那么输出只有一个整数,表示最少交换的次数;如果k=2,那么输出有两行,第一行是一个整数,表示最少交换的次数,第二行有一个整数,表示第一步的方案数。


分析

  • 找到所有的循环, 每个循环中置换次数是这个循环中元素的个数-1. 把所有的都加起来就得到总次数. 这个可以参考codevs的排序的代价, 不过这里代价都是0.
  • 如果再来做第二问, 在一个循环中, 假设循环中元素的个数是n, 第一步选两个元素交换, 第一个元素有n种选择, 第二个元素有n-1种选择. 最终交换a和b与交换b和a是一样的, 所以这个循环中第一步选择的方案数是n*(n-1)/2.

题目二

描述

在某一时刻,存活的狮子有地位高低之分,能力值高的地位高,能力值相同的当中年龄大的地位高。任何时刻,地位最高的狮子可以吃掉地位最低的狮子,但如果这样做,地位最高的狮子能力值会减少它吃掉的狮子的能力值。假定所有狮子都足够聪明,并且在保证自己不死的前提下会尽量吃掉别的狮子。现给出每个狮子的年龄和能力值,求哪些狮子死了。

输入格式
输入有2行,第一行有一个正整数n。第二行有n个用空格隔开的正整数,按年龄从小到大依次给出每个狮子的能力值,并按输入顺序编号为1~n。
输出格式
输出有2行,第一行有一个整数m,表示死去的狮子的个数。第二行有m个用空格隔开的正整数,为死去的狮子在输入中的编号(请从小到大输出)。


分析

  • 看来直接递归是最好的办法了.
    在递归过程中用一个栈来保存先后死掉的狮子. 先假设当前最厉害的狮子A吃掉了最弱的狮子B, 递归下一层直到只剩一只狮子, 然后返回处理, 如果当前A在后来被吃掉了, 那么狮子A一定不会吃掉B, 就在栈中找到B, 把它和以上的元素都退栈. 吃掉的狮子个数修改为当前的递归层数.

  • 还有其他办法不用递归, 但都看不太懂. 递归最直接了.

  • 狮子的信息可以用pair存, 自动按两维排序.

题目四

描述

背景
有两种液体A和B,等量混合时完全反应生成气体挥发不留渣;不等量混合时等量部分发生上述反应,多出部分留下。
描述
现有n个杯子排成一排,每个杯子里装有一种液体。我们可以进行若干次如下操作:选择两个相邻的杯子,这两个杯子中的液体种类必须是不同的,将其中一个杯子里的液体全部倒入另一个杯子中(杯子容积很大,不考虑溢出),反应充分之后拿走所有空杯子(拿走空杯子可以使原本不相邻的杯子变得相邻)。给出一个初始状态,求最少剩下多少个杯子。
输入格式
输入有n+1行,第一行有一个正整数n,接下来的n行,每行格式为“Vi Ki”,Vi为一正整数,表示这排杯子从左数第i个杯子的液体量,Ki为一个字符A或B,表示这排杯子从左数第i个杯子里液体的种类。
输出格式
输出有一个整数,表示最少剩下的杯子数。


分析


代码

https://code.csdn.net/snippets/615224

posted @ 2015-03-09 20:44  wfwbz  阅读(109)  评论(0编辑  收藏  举报