10.24南海NOIP模拟测解题报告

这次的模拟测验疏忽颇多,没有掌控好到时间,同时还不小心用了“文件替换”:10.24南海NOIP模拟测解题报告 - wenjianwei1 - 算法的设计

  而最后一题也是想到了解法没有写出来,第三题写的时候写错了。所以这表现出我的编程能力尚有所不足,还需打好基础。

废话不多说了,直接就上题解。

   1、扑克牌 

    a.pas/cpp/c)

【题目描述】

FJ有一副扑克,有52张牌,分为方块、梅花、红桃、黑桃,共4大类,每类都是有13张牌。我们用P表示方块类,用K表示梅花类,用H表示红桃类,用T表示黑桃类。每一类用数字010203,......13 表示13张牌,那么方块类的13张牌就是:P01P02P03, ...P10P11P12P13。同理,梅花类的13张牌就是:K01K02K03...K10K11K12K13。红桃类,黑桃类的也同理。

   FJ现在教Bessie认扑克牌,FJ给出一个字符串S,问字符串中是否有重复的扑克牌?如果有重复的扑克牌,Bessie要输出“GRESKA”。如果没有重复的扑克牌,如果FJ要把一副扑克的52张牌全部给Bessie的话,除了已经给了字符串S代表的扑克牌,还缺多少张方块牌?还缺多少张梅花牌?还缺多少张红桃牌?还缺多少张黑桃牌?

【输入格式】

    输入文件名为a.in

    一个字符串S,表示FJ已经给了这些扑克牌给Bessie。字符串的每三个连续的字符表示一张扑克牌。S的长度不超过1000

【输出格式】

    输出文件名为a.out

如果有重复的扑克牌,输出“GRESKA”(双引号不用输出)。

否则输出4个整数,空格分开,分别表示还缺的方块扑克牌的数量、还缺的梅花扑克牌的数量、还缺的红桃扑克牌的数量、还缺的黑桃扑克牌的数量。

输入样例:  a.in

输出样例: a.out

样例解释

P01K02H03H04

12 12 11 13

给出了4张扑克牌,其中第1张是方块,第2张是梅花,第3张和第4张是红桃,没有给出黑桃,给出的没有重复的扑克牌,因为4大类的扑克牌都是13张的,所有还缺方块牌12张,还缺梅花牌12张,还缺红桃牌11张,还缺黑桃牌13张。

H02H10P11H02

GRESKA

因为给出的两张H02,有重复。

P10K10H10T01

12 12 12 12

没有给出重复的牌,而且各类都是给出1张,所以各类扑克牌都是缺12张。


【题意分析】
给出若干张牌,问有没有重复的牌,若没有则问缺少几张牌。
【解题思路】
这题相当水,只需要读进来的时候三个三个字符读,再略微处理一下,排一排序,C++甚至直接可以利用sort()和unique()直接过……我不想再说什么了,这题真的很简单。

2、购书

(b.pas/cpp/c)

【题目描述】

Bessie买了N本书,第i本书的价格是Price[i]。书店老板有个规定,如果把任意的3本书放在一起打包,那么这3本书之中价格最低的那本书可以不用给钱。那么Bessie应该如何打包,才能用最少的钱把这N本书买回来?注意:是每3本书都可以打包,你不能尝试着把4本书放在一起打包,也不能把2本书放在一起打包。

【输入格式】

输入文件名为b.in

第一行,一个整数N 1<=N<=100000

接下来有N行,第i行是一个整数,表示第i本书的价钱Price[i] 1<=Price[i]<=100000

【输出格式】

   输出文件名为b.out

一个整数,最少的钱。

【数据规模】

   50%的数据,N <= 2000

输入样例   b.in

输出样例  b.out

样例解释

4

3

2

3

2

8

可以把前3本书打包,这样第2本书不用给钱。

6

6

4

5

5

5

5

21

分两次打包,可以省下9元。


【题意分析】
将给出的价值三个一组(剩下的不管),问怎样可以将所有组中的最小值之和最大化。
【解题思路】
一看就是贪心。将全部求和,再将其从大到小排序,扫一遍将相应的书本剔除掉。举个例子,给出的输入样例2为例:

价值 6 5 5 5 5 4
分组 1 1 1 2 2 2
所以上面的这个例子的结果就是6+5+5+5+5+4-5-4=21了。关于贪心的正确性也很容易得证,比如我们已经选择了两个数,那接下来我们要想省的钱最多,那就应该选剩下来里最大的数,也就是第三大的数。而已经选的数必定只能是第一和第二大的数,因为比如说选了一个第四大的,那这个第四大的就成为了最小,不够划算。
所以这题只需要排个序,然后从大到小剔除相应的书本就能过了,时间复杂度O(Nlog2N)。

3折纸

c.pas/cpp/c

【题目描述】

FJ给你一张长方形的白纸,宽度是W,高度是H。但是你真正需要的是一张面积是A的长方形白纸,于是你可能需要多次折纸,每次折纸的过程中,要同时遵守如下的两个规则:

1、你选择一条直线,然后把白纸沿着直线折过来。你务必要保证你选择的这条直线是平行于白纸的某一条边,则可以横折或者竖折,不能斜折,折完之后白纸还是长方形形状。

2、每折纸一次,都要保证折纸之后,白纸的长度和宽度都是整数。

在以上的前提下,你至少需要折纸多少次,才能得到面积是A的白纸?如果不可能完成任务则输出-1,否则输出最少的折纸次数。

【输入格式】

  输入文件名为c.in

     第一行,三个整数:WHA  1<=WH<=1000000000 1<=A<=100000

【输出格式】

     输出文件名为c.out

     最少的折纸次数。不能完成任务则输出-1

【数据规模】

     对于60%的数据,1<=WH<=200 1<=A<=200

 

输入样例   c.in

输出样例   c.out

5  3  12

1

2  2  3

-1

4  4  1

4

127  129  72

8

1  100000   100000

0


【题意分析】
这题的题目不难理解,就是用最少的折纸次数折成指定的面积,用另一种方式来说,就是在所有的可能最后边长中,用最少的折纸次数折出相应的边长。

【解题思路】
这道题的解题思路其实是很简单的,就是不断对半折。如果最后折过了那就停止,所以最终的时间复杂度大概是O(sqrt(N)*log2N)。对于这题的数据规模,应该还是可以用log()函数变成O(sqrt(N))。

4、足球队

 (d.pas/cpp/c)

【题目描述】

     一支足球队都由11名球员组成的,除了1名守门员外,还有10名球员,这10名球员有的踢后卫位置,有的是踢中锋位置,有的是踢前锋位置。不同的球队可能喜欢的阵型可能不一样,有的球队喜欢4-4-2阵型(4名后卫4名中锋2名前锋),有的球队喜欢3-5-2阵型(3名后卫5名中锋2名前锋),也有球队喜欢5-3-2阵型(即5名后卫3名中锋2名前锋)。我们约定,后卫用大写字母‘O’表示,中锋用大写字母‘V’表示,前锋用大写字母‘N’表示。但是有的球员能踢多个位置,例如某个球员能踢的位置是OV,那么表示该球员既能踢后卫又能踢中锋,又比如某个球员是NV,则表示该球员既能踢前锋又能踢中锋,如果某个球员是VON,则表示该球员能踢中锋、后卫、前锋。总之,一个球员能踢的位置根据给出的字母就可以确定了。

现在给出M个候选球员,知道每个球员能踢的位置。现在足球教练想安排的阵型是:x-y-z,表示要从M名球员中挑出10人,安排x人踢后卫,y人踢中锋,z人踢前锋,其中x+y+z=10,且0<=x,y,z<=10。那么足球教练有多少种不同的选择方案呢?注意:如果被选中的10人不同,那么肯定是不同的方案。10人被选中之后,如果安排某球员踢的位置不同,也算不同的方案。请看样例帮助理解。

【输入格式】

  输入文件名为d.in

         第一行的格式是:x-y-z,其中x,y,z是三个整数,且x+y+z=10,且0<=x,y,z<=10,表示教练的阵型。

     接下来一行是一个整数M,表示有M名候选球员。10<=M<=22

     接下来是M行,每行描述一个球员能踢的位置。

【输出格式】

     输出文件名为d.out

     一行,一个整数,表示不同的方案数。

【数据规模】

      60%的数据,M=10

输入样例:  d.in

输出样例:  d.out

样例解释

4-4-2

11

O

O

O

V

V

V

V

N

N

OV

OV

13

 

【题意分析】
题意挺容易理解的,就是求方案数。
【算法分析】
记忆化搜索或者动态规划,其实实现起来也还是挺简单的。动态规划方程,就是设f[n][x][y][z]为在n个人中选x个前锋,y个中锋,z个后卫,接着就不难想了,f[n][x][y][z]=f[n-1][x-1][y][z](第n个人能做前锋)+f[n-1][x][y-1][z](第n个人能做中锋)+f[n-1][x][y][z-1](第n个人能做后卫),所以其实还是挺简单的。不过其实这个问题在根本上可以变成一个分组的背包问题,比如说第n个人能做的位置数,就变成了三个位置的物品,并且分成一组,再要求每一组只能选一个,接着求一个方案数,就变成了一个O(n^3)空间复杂度的背包了。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值