题意:
两个人进行网球比赛,赢一球得一分,每局有T分,一局胜利后比分会被刷新,当某人赢够S局后比赛结束;现 在输入n个数,表示一场比赛中两个人的分别得分,1表示Petya , 2表示Gena. 要求依据这组得分输出所有可能 的比分回合制度,顺序为以S递增,S相同以T递增。
题解:
这道题的关键在于理解好题意,题目要求输出所有可能的回合制,我们可以由1至最大得分枚举所有情况,然 后再每次判断是否满足比赛规则。
注意点:
对于得分的处理是关键,如果从头至尾遍历时间复杂度为O(n*n),一定会超时,所以可以再输入的时候直 接把得分转化为当前每个人的总得分存储,这样可以在每次的 判断中利用二分查找,定位最先达到满足分 数的人,胜局加一。当一局比赛结束后,得分会被刷新,所以每局结束时都要将两人得分同步到胜者的当 前位置,再进行下一次运算。
不满足题意的情况:
1.以T分制计算,最终结束时未打满一整局;
2.winner与得分最高的人不相同;
3.两个人得分相同;
代码实现:
<span style="font-size:14px;">#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <algorithm>
#include <cstring>
#include <vector>
using namespace std;
struct option{
int s;
int t;
bool operator <(const option &next) const
{
if(this->s==next.s)
return this->t < next.t;
else
return this->s < next.s;
}
};//定义结构体储存满足条件的回合制度,重载'<'号方便后期sort排序
vector<int> num1;//储存'1'总得分
vector<int> num2;//储存'2'总得分
vector<option> oLis;//储存
int n,sum1,sum2;
int winner;//将胜者(who get the key point)标记
bool solve(int);
int main()
{
scanf("%d",&n);int a;
sum1=0;sum2=0;
for(int i=0;i<n;i++)
{
scanf("%d",&a);
if(a==1)
sum1++;
else
sum2++;
if(i==n-1)
winner=a;
num1.push_back(sum1);
num2.push_back(sum2);
}
int sum=sum1>sum2?sum1:sum2;
for(int i=1;i<=sum;i++)//从1到最大得分枚举
solve(i);
sort(oLis.begin(),oLis.end());
printf("%d\n",oLis.size());
for(int i=0;i<(int)oLis.size();i++)
printf("%d %d\n",oLis[i].s,oLis[i].t);
return 0;
}
bool solve(int x)
{
int tmp1,tmp2;//储存最先达到指定分数的位置
int pos1,pos2;//储存1,2当前实际得分
int score1,score2;//储存1,2所赢回合数
bool flag=true;
pos1=0;pos2=0;
score1=0;score2=0;
for(int i=0;i<n;i++)
{
//二分找到最早满足得分的回合
tmp1=lower_bound(num1.begin(),num1.end(),pos1+x)-num1.begin();
tmp2=lower_bound(num2.begin(),num2.end(),pos2+x)-num2.begin();
if(tmp1!=n||tmp2!=n)//必须当两人都达到最高得分时跳出循环
{
if(tmp1<tmp2)//1先满足条件
{
score1++;
//同步得分:将两人当前得分定位到同一位置
pos1=num1[tmp1];
pos2=num2[tmp1];
}
else
{
score2++;
pos1=num1[tmp2];
pos2=num2[tmp2];
}
}
else//两人同时达到最高分
{
tmp1=tmp2=n-1;
//此时表示结束时仍未打完一局
if(num1[tmp1]!=pos1||num2[tmp2]!=pos2)
flag=false;
break;
}
}
if(flag)
{
//不满足题意情况
if((winner==1&&score2>score1)||(winner==2&&score1>score2)||(score1==score2))
return false;
option tem;
tem.s=score1>score2?score1:score2;
tem.t=x;
oLis.push_back(tem);
return true;
}
return false;
}</span>