题面
题面翻译
这个题目是说,Berland 的国家队成功加入一场足球联赛的半决赛。下面是球赛的规则:
· 两队比赛,比赛结束后哪支队伍进的球比对方队伍多,哪方获胜。
· 胜利得3分,平局两队各得1分,失败不得分(得0分)。
· 这四队中得到第一或第二的队伍进入下一轮。
每个队伍的名次是由总得分来算的:分越多,名次越高。如果两个队伍有同样的分,以下列方式来决定高低(越靠前的规则越优先考虑,如果还是不能分出高低,再往下判断。下列第一个权重最高):
· 每个队的进球数减去失球数,得到的结果越高排名就越高。
· 总进球数越高,排名就越高。
· 如果以上都不行的话,则以字典序排列。
现在还有一场比赛未打。一共6场比赛,已知前五场的队伍与得分。某个队伍和Berland还没交战。教练想让你找到如此X:Y(X是Berland的得分,Y是另一只球队的得分),可以满足下列条件:
· X>Y,Berland得赢;
· Berland赢后,得进前二名;
· 如果不止一种答案,尽可能让X-Y小;
· 如果还是有很多答案(不止一个),你应该让Y尽可能小。
输入格式:
一共有五行。
每一行都是以“team1 team2 goals1:goals2”(没引号)形式出现。表示team1跟team2交战一局。team1进了goal1个球,team2进了goal2个球。team1和team2都是非空字符串,并且都是大写字母,总长度不超过20。goal1和goal2都是0~9的正整数。
Berland队名字是"BERLAND"。保证只有Berland和另一支队伍打了2场比赛,其他队打了3场。
输出格式:
输出比分X:Y。X是Berland分数,Y是另一只球队的分数。如果怎么样也无法得到第一或第二,输出一行"IMPOSSIBLE"(没引号)。
提示:最后一场分数也不一定小,比如10:0这种情况。
先说几句
很好的枚举法、STL 练习题。再说几句,感觉题目有点像,就是让 Berland 队和另一个队踢假球,使得 Berland 队成功晋级。但是,这场假球要做得尽可能真。带着这样的理解会更容易理解题意。
解题思路
在已知的场次中,把每个队伍的各种得分统计好。使用结构体更好地存储得分信息。如下。
struct node
{
string name; // 名称
int score; // 得分
int jsq; // 净胜球
int zsq; // 总进球数
node() // 初始化
{
score=jsq=zsq=0;
}
};
有结构体,就一定有比较函数。按照题目描述写,不是很难。
bool cmp(node a, node b)
{
if(a.score!=b.score) // 1.得分
return a.score>b.score;
if(a.jsq!=b.jsq) // 2.净胜球
return a.jsq>b.jsq;
if(a.zsq!=b.zsq) // 3.总进球数
return a.zsq>b.zsq;
return a.name<b.name; // 4.队名字典序
}
接下来进入主函数。输入时,用 map 嵌套 struct 记录每个队伍的详细信息。先使用 c n t cnt cnt 统计比赛次数,就可以知道 Berland 的对手是谁。
然后,枚举对手得分
y
y
y 和净胜球数
d
d
d,则 Berland 得分
x
=
y
+
d
x=y+d
x=y+d。拷贝一个新 map,改变双方得分信息,提取出 vector,排序,检查 Berland 的排名。如果循环完了没有解,输出 IMPOSSIBLE
。
y y y 和 d d d 的枚举范围在 100 100 100 以内即可。
奉上代码
// 200C Football Championship
#include <bits/stdc++.h>
#define var long long
#define SIZE 200010
#define debug(x) cout<<#x<<":"<<x<<endl;
using namespace std;
struct node
{
string name;
int score;
int jsq;
int zsq;
node()
{
score=jsq=zsq=0;
}
};
bool cmp(node a, node b)
{
if(a.score!=b.score)
return a.score>b.score;
if(a.jsq!=b.jsq)
return a.jsq>b.jsq;
if(a.zsq!=b.zsq)
return a.zsq>b.zsq;
return a.name<b.name;
}
int main()
{
map<string, node> m;
map<string, int> cnt;
for(int i=0; i<5; i++)
{
string s1, s2; cin>>s1>>s2;
cnt[s1]++; cnt[s2]++;
m[s1].name=s1;
m[s2].name=s2;
int x, y;
scanf("%d:%d", &x, &y);
m[s1].zsq+=x;
m[s2].zsq+=y;
m[s1].jsq+=x-y;
m[s2].jsq+=y-x;
if(x>y)
m[s1].score+=3;
if(y>x)
m[s2].score+=3;
if(x==y)
{
m[s1].score++;
m[s2].score++;
}
}
string another;
for(auto x:cnt)
if(x.first!="BERLAND" && x.second==2)
{
another=x.first;
break;
}
/*
for(auto x:m)
{
cout<<x.second.name<<endl
<<x.second.score<<endl
<<x.second.jsq<<endl
<<x.second.zsq<<endl
<<endl;
}
*/
for(int d=1; d<=100; d++)
for(int y=0; y<=100; y++)
{
//debug(d);
int x=y+d;
auto nm=m;
nm["BERLAND"].score+=3;
nm["BERLAND"].jsq+=d;
nm[another].jsq+=-d;
nm["BERLAND"].zsq+=x;
nm[another].zsq+=y;
vector<node> v;
for(auto t:nm)
v.push_back(t.second);
sort(v.begin(), v.end(), cmp);
if(v[0].name=="BERLAND" || v[1].name=="BERLAND")
{
cout<<x<<':'<<y;
return 0;
}
}
puts("IMPOSSIBLE");
return 0;
}