2019独角兽企业重金招聘Python工程师标准>>>

3046. 足球

Description

众所周知,一只足球队由11球员组成,其中有一名守门员和一名队长。 现在,有22人组成的一个候选名单,从中要选出11人参加比赛。选拔规则如下: 首先提供一个阵型,例如,4-4-2。第一个4表示有4名后卫,第二个4表示有4名中场,第三个2表示有2名前锋。当然,还有一个位置就是留给守门员的。 每个人都有自己唯一能打的位置(前锋、中场、后卫、守门员)。在每个位置上,以球员的编号为关键字,从小到大依次选取。 选出球队后还要选出队长。队长是球队中参加比赛次数最多的球员。如果有并列,取编号较大的球员做队长。

Input Format

前22行每行按如下格式表示出一名球员的信息:
Number Name Role year1-year’1 year2-year’2 …
整数Number(<=100)是该球员编号。字符串Name(length<=20)是该球员名字。字符Role是该球员所能打的位置(S前锋、M中场、D后卫、G守门员)。每一对yeari-year’i(yeari<=year’i) 表示该球员效力的时间段,例如2001-2002表示该球员效力了两年2001年和2002年。至少有1对年份,最多20对年份。年份是一个四位数。保证任意两段年份不会重叠。球员的编号在球队中是唯一的。
第23行给出一个阵型,例如4-4-2。保证阵型有且仅有3个正整数组成,且和等于10。例如,4-3-2-1是不合法的。

Output Format

输出选出的11名球员,每一行包括球员编号,姓名,场上所打位置。之间用一个空格隔开。球员按守门员、后卫、中场、前锋的顺序排序,相同位置按编号从小到大排序。如果一名球员是队长,那么无论他打什么位置,都放在序列的第一个。如果无法找出11个满足条件的球员,输出“IMPOSSIBLE TO ARRANGE”。

Sample Input

9 PlayerA M 2000-2001 2003-2006
2 PlayerB M 2004-2006
10 PlayerC D 2001-2005
1 PlayerD D 2000-2001 2002-2004
11 PlayerE S 2003-2006
8 PlayerF M 2005-2006
22 PlayerG S 2005-2006
25 PlayerH G 2000-2001 2002-2003 2005-2006
6 PlayerI D 2003-2006
26 PlayerJ D 2003-2004 2000-2001
18 PlayerK M 2003-2004
19 PlayerL M 2000-2001 2003-2006
7 PlayerM S 2003-2006 1999-2001
21 PlayerN S 2003-2006
13 PlayerO S 2005-2006
15 PlayerP G 2001-2006
14 PlayerQ D 2003-2004
5 PlayerR S 2000-2005
20 PlayerS G 2000-2002 2003-2003
12 PlayerT M 2004-2005
3 PlayerU D 2000-2005
4 PlayerZ M 2001-2004
4-4-2

Sample Output

7 PlayerM S
15 PlayerP G
1 PlayerD D
3 PlayerU D
6 PlayerI D
10 PlayerC D
2 PlayerB M
4 PlayerZ M
8 PlayerF M
9 PlayerA M
5 PlayerR S

Limits

Time limit: 1000ms, memory limit: 50000kb.

===============================================================

题解正文

===============================================================

  1. 题目分析:

    首先我们要知道这道题目给了什么信息:

    1. 这是张由22个球员构成的表。

    2. 每个主球运动员都有 编号(唯一)、名字(没有用)、位置(D M S G)、年份(这个年份纯粹是搞出来糊弄人的,我们只要通过一定手段算出来到底有多少年即可)

    3. 这题很好的地方是年份一定是四位数并且一定是长度为9的字符串:XXXX-XXXX,这个非常便于我们计算该运员干了多少年,干的年份越久表示参加的比赛越多 = =。

    4. 输出的要求其实也很简单,满足阵型是首要条件,接下来是选取相应的人,注意到同位置选取编号小的;

    5. 选队长时优先选年份多的,再次是编号大的(和上面不同)。

  2. 算法实现:

    1. 输入

      1. 考虑到运动员这一独立的对象,又懒得写类,于是用struct来构造一个player,这个struct叫ply

      2. struct ply{int num;  //编号string name; //名字char pst; //位置int years; //年份bool used; //是否已经被选取,必要性不太大,保险起见而已
        }players[22],team[11]; //左边是备选的22个备胎,右边是被选中的11个孩子
      3. 上面提到的pst其实用枚举类型更好,直接给那几个位置赋G0 D1 M2 S3 这样输出时排列非常方便

      4. 输入流处理:

      5. void init()
        {cin >> players[0].num; //这里可以看到我编号是额外处理的,这是因为读取年份时为了简便string tmp;            //不得不多读一个字符串,导致下一个球员的编号被读入了tmp中for(int i = 0; i < 22; ++i){cin >> players[i].name  //直接存就好了>>players[i].pst;players[i].years = 0;while(cin >> tmp && tmp.length() == 9) //这就是为了及时停下来,但无可避免地{                                      //读取了下一个球员的编号int a, b;a = 1000 * (tmp[0] - '0') +       //计算年份100 * (tmp[1] - '0') +10 * (tmp[2] - '0') + (tmp[3] - '0');b = 1000 * (tmp[5] - '0') +100 * (tmp[6] - '0') +10 * (tmp[7] - '0') + (tmp[8] - '0');players[i].years += (b - a) + 1; //注意这个加一,小学常见的应用题陷阱}if(i < 21) players[i+1].num = (int)atof(tmp.c_str());//string直接转成intplayers[i].used = 0; //初始化}sort(players, players + 22, cmp1); //排序优先位置升序,其次编号升序cin >> tmp;D = tmp[0] - '0';M = tmp[2] - '0';S = tmp[4] - '0';
        }
      6. 详细讲一下cmp的使用,我使用了三个cmp,分别有不同的用处,他们极大地维护了代码的简洁和准确

      7. inline bool cmp1(ply a, ply b)
        {  //优先位置升序,其次编号升序if(a.pst == b.pst)else return a.num < b.num;else return a.pst < b.pst;
        }
        //选队长专用
        inline bool cmp2(ply a, ply b)
        {    //优先年份,年份一样按大序号优先if(a.years == b.years ) return a.num > b.num;else return a.years > b.years;
        }//最后除了队长之外的人进行排序
        inline bool cmp3(ply a, ply b)
        {if(a.pst == 'G')return 1;//这两条确保后卫排在最前面if(b.pst == 'G')return 0;else//恰好利用了ascii中D < M < S 这一原则 不过如果输出顺序不按GDMS 我们也可以通过//enum来安排顺序值if(a.pst == b.pst) return a.num < b.num;else return a.pst < b.pst;}
    2. 选拔

      1. 选拔就比较简单了,主要是用了一个变量t来引导球员储存到team中并且计算一共有多少球员满足要求,当且仅当t==11时满足要求,因此可以直接用t来判断是否有解,我第一次提交就是忘记考虑无解的情况了

      2. 另外输入的时候读取了四个位置所要求的值(当然G默认为1)通过while循环达到读取的目的,不会漏掉也不会多取。

      3. 具体请看最终代码

    3. 输出

      输出很简单了。如果有解就对team数组进行排序,然后打印出来。无解就输出那句话即可。

  3. 代码送上,有很多不足,大家看看就好~欢迎讨论

#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
#include<stdlib.h>
#include<stdio.h>using namespace std;struct ply{int num;string name;char pst;int years;bool used;
}players[22],team[11];
int D, M, S, G, L;
bool flag = 1;
inline bool cmp1(ply a, ply b)
{if(a.pst == b.pst){if(a.num == b.num){if(a.years == b.years) return a.name < b.name;else return a.years > b.years;}else return a.num < b.num;}else return a.pst < b.pst;
}
inline bool cmp2(ply a, ply b)
{if(a.years == b.years ) return a.num > b.num;else return a.years > b.years;
}inline bool cmp3(ply a, ply b)
{if(a.pst == 'G')return 1;if(b.pst == 'G')return 0;elseif(a.pst == b.pst) return a.num < b.num;else return a.pst < b.pst;}
void init()
{cin >> players[0].num;string tmp;for(int i = 0; i < 22; ++i){cin >> players[i].name>>players[i].pst;players[i].years = 0;while(cin >> tmp && tmp.length() == 9){int a, b;a = 1000 * (tmp[0] - '0') +100 * (tmp[1] - '0') +10 * (tmp[2] - '0') + (tmp[3] - '0');b = 1000 * (tmp[5] - '0') +100 * (tmp[6] - '0') +10 * (tmp[7] - '0') + (tmp[8] - '0');players[i].years += (b - a) + 1;}if(i < 21) players[i+1].num = (int)atof(tmp.c_str());players[i].used = 0;}sort(players, players + 22, cmp1);cin >> tmp;D = tmp[0] - '0';M = tmp[2] - '0';S = tmp[4] - '0';
}
void select()
{int t = 0;for(int i = 0; i < 22; ++i){while(D && players[i].pst == 'D'){team[t++] = players[i];++i, --D;}if(players[i].pst == 'G')team[t++] = players[i];while(players[i].pst == 'G')++i;while(M && players[i].pst == 'M'){team[t++] = players[i];++i, --M;}while(S && players[i].pst == 'S'){team[t++] = players[i];++i, --S;}}if(t == 11){sort(team, team + 11, cmp2);sort(team + 1, team + 11, cmp3);}else flag = 0;
}
int main()
{init();select();if(flag)for(int i = 0; i < 11; ++i)cout<<team[i].num<<" "<<team[i].name<<" "<<team[i].pst<<endl;else cout<<"IMPOSSIBLE TO ARRANGE"<<endl;}

转载于:https://my.oschina.net/xueyang/blog/288014

SJTU OJ 3046 足球 题解相关推荐

  1. Comet OJ - Contest #11 题解赛后总结

    Solution of Comet OJ - Contest #11 A.eon -Problem designed by Starria- 在模 10 意义下,答案变为最大数的最低位(即原数数位的最 ...

  2. Jarvis OJ 刷题题解 RE

    最近比赛有点多 决定把 脱强壳  还有软件调试 还有 漏洞战争 放一放 先刷一些题目压压惊 最终还是选择了 Jarvis OJ   (buuctf 太卡了... 以前也写过几道  === 希望能把上面 ...

  3. 【算法学习笔记】65. 双向扫描 SJTU OJ 1382 畅畅的牙签盒

    http://acm.sjtu.edu.cn/OnlineJudge/problem/1382 注意到 排序之后 i从前向后扫描时,cur恰好是从后向前的,所以即使是双重循环,也是O(n)的算法. # ...

  4. 【算法学习笔记】43.动态规划 逆向思维 SJTU OJ 1012 增长率问题

    1012. 增长率问题 Description 有一个数列,它是由自然数组成的,并且严格单调上升.最小的数不小于S,最大的不超过T.现在知道这个数列有一个性质:后一个数相对于前一个数的增长率总是百分比 ...

  5. 【算法学习笔记】57. 前缀树 字典序优化技巧 STL学习 SJTU OJ 1366 前缀匹配

    Description 给出一个总字符个数大小不超过1,000,000的字典(这个字典的单词顺序不为字典序)和不超过1000个长度不超过1000的前缀,输出字典中匹配该前缀,字典序为K_i的单词在字典 ...

  6. 【算法学习笔记】35.高精度 竖式乘法 SJTU OJ 1274

    Description 输入a,b 输出a*b的竖式乘法,格式见样例. Sample Input1 11 9 Sample Output1 119 -- 99 Sample Input2 10 10 ...

  7. Comet OJ - Contest #2题解

    传送门 既然没参加过就没有什么小裙子不小裙子的了-- 顺便全是概率期望真是劲啊-- 因自过去而至的残响起舞 \(k\)增长非常快,大力模拟一下就行了 int main(){scanf("%l ...

  8. 【算法学习笔记】83.排序辅助 动态规划 SJTU OJ 1282 修路

    此题倒是能用贪心骗点分... 其实对于每一个位置 , 我们知道最后的改善结果一定是原数列中的数 . (因为要尽量减少消耗, 可以考虑减小至和相邻的相同) 有了这个结论之后, 我们就考虑用dp来做这件事 ...

  9. Comet OJ - Contest #0题解

    传送门 菜爆了--总共只有一道题会做的--而且也没有短裙好难过 为啥必须得有手机才能注册账号啊喂--歧视么-- \(A\) 解方程 推一下柿子大概就是 \[x-\sqrt{n}=y+z+2\sqrt{ ...

最新文章

  1. 十个效果酷炫的Linux系统操作指令(像黑客帝国般的效果~)
  2. mysql 导入数据 1215_12、mysql导入数据
  3. MM中如何更改物料的评估类
  4. 2013年人人校园招聘笔试题
  5. CodeForces - 1088E Ehab and a component choosing problem(树形dp)
  6. CloudCC:2017年下半年企业移动CRM市场风向窥测
  7. 在 Apex 中得到 sObject 的信息
  8. 用asp.net实现微博系统_微信几亿人在线的点赞、取消点赞系统,用Redis如何实现?...
  9. Proxy动态代理代码示例
  10. Milano Store OpenCart 2.0 主题模板 ABC-0473
  11. 读凯文·米特尼克的黑客传奇经历
  12. Unity 资源加载卸载过程
  13. 虚拟化安全怎么做?靠安全设备虚拟化还是换个思路?
  14. Java实现推箱子小游戏
  15. 解决 EIGEN_STACK_ALLOCATION_LIMIT, OBJECT_ALLOCATED_ON_STACK_IS_TOO_BIG 报错
  16. 下单后,订单拆单能怎拆?
  17. 虚拟机设置BT4上网
  18. GSoC、CSDN 开源夏令营--我的开源社区之旅
  19. 基于高德SDK实现跑步时轨迹渐变功能
  20. HNU君陌:写点其他的

热门文章

  1. jsp中如何将Java对象转成js对象?
  2. TCP滑窗与拥塞控制
  3. php composer使用过程
  4. 《软件工程概论》第四章核心内容
  5. a标签在ie6和ie7下面换行显示问题解析
  6. [转]不知道能否解决先转下来再说不显示删除回复显示所有回复显示星级回复显示得分回复 没有找到MSVR90D.dll因此这个应用程序未能启动...
  7. PHP创建圆柱体的类,创建一个类
  8. python中loop的用法_python-在Tensorflow中使用tf.while_loop更新变量
  9. 太强了,300分钟撸一个基于redis的亿级用户高并发系统
  10. 如何领导团队做好技术债管理?