题意:
两个人进行网球比赛,赢一球得一分,每局有T分,一局胜利后比分会被刷新两个人的分数都重新赋为0,当某人赢够S局后比赛结束;现在输入n个数,表示一场比赛中两个人的分别得分,1表示Petya , 2表示Gena. 要求依据这组得分输出所有可能的比分回合制度,顺序为以S递增,S相同以T递增。
思路:
借鉴了别人的思路,直接暴力了T的值,枚举了T的值后可以二分两个人有人胜出时的分数,这里我用的是把两个人的分数都用前缀和处理一下,找出来后比较两个人那个完成的比较早,就赢得比赛。这一题有挺多情况有特判的,挺烦的。。。
代码:
#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
typedef pair<int ,int > P;
const int MAX_N = 1e5+9;
int vec1[MAX_N];
int vec2[MAX_N];
vector <P> out;
bool cmp(const P&A,const P&B)
{
if(A.first!=B.first) return A.first <B.first;
else return A.second < B.second;
}
int main()
{
int N,M,T;
while(cin>>N)
{
memset(vec1,0,sizeof(vec1));
memset(vec2,0,sizeof(vec2));
out.clear();
int win = 0;
for(int i=1; i<=N; i++)
{
scanf("%d",&T);
if(i == N)
{
if(T == 1 ) win = 1;
else win = 2;
}
if(T == 1) vec1[i] = 1;
else vec2[i] = 1;
vec1[i] += vec1[i-1];
vec2[i] += vec2[i-1];
//cout<<vec1[i]<<"....."<<vec2[i]<<endl;
}
//cout<<vec1[N]<<"...."<<vec2[N]<<endl;
if(vec1[N] == vec2[N])
{
printf("0\n");
continue;
}
int ans = 0;
for(int t=1; t<=max(vec1[N],vec2[N]); t++)
{
int p1 = 0;
int p2 = 0;
int num1 = 0;
int num2 = 0;
while(1)
{
p1 += t;
p2 += t;
if(p1 > vec1[N] && p2 > vec2[N]) break;
int a = lower_bound(vec1+1,vec1+N+1,p1)-vec1;
int b = lower_bound(vec2+1,vec2+N+1,p2)-vec2;
if(a<b) num1++;
else num2++;
int res = min(a,b);
//cout<<t<<" "<<a<<"....."<<b<<endl;
if(res >= N)
{
if(num1 != num2 )
{
if(num1 > num2 && win == 2) break;
else if(num1<num2 && win == 1) break;
//cout<<num1<<"...."<<endl;
ans ++;
out.push_back(make_pair(max(num1,num2),t));
}
break;
}
p1 = vec1[res];
p2 = vec2[res];
}
}
cout<<ans<<endl;
int s = out.size();
sort(out.begin(),out.end(),cmp);
for(int i=0;i<out.size();i++)
{
cout<<out[i].first<<" "<<out[i].second<<endl;
}
}
return 0;
}