题意:进行若干场比赛,每次比赛两人对决,赢的人得到1分,输的人不得分,先得到t分的人获胜,开始下场比赛,某个人率先赢下s场比赛时,游戏结束。
现在给出n次对决的记录,问可能的s和t有多少种,并按s递增的方式输出。
题解:n方T只能说明头硬
但是 n/1+n/2+...+n/n=nlogn
我们可以用这个公式进行优雅的暴力
记录第i个1和2出现的位置
然后直接暴力比对过去
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<vector>
using namespace std;
int ans,a[100005],v[200005],p[200005];
struct node{
int d,t;
bool operator <(const node& a)const{
return d<a.d;
}
}e[100005];
vector<int>sp;
int main(){
int n,i,j;
scanf("%d",&n);
for(i=1;i<=200004;i++)v[i]=p[i]=100004;
for(i=1;i<=n;i++){
scanf("%d",&a[i]);
if(a[i]==1)v[++v[0]]=i;
else p[++p[0]]=i;
}
for(i=1;i<=n;i++){
int num1=0,num2=0,ch1=0,ch2=0,flag=1;
int now=1;
while(now<=n){
if(v[num1+i]==100004&&p[num2+i]==100004){
flag=0;
break;
}
if(v[num1+i]<p[num2+i]){
ch1++;
num1+=i;
num2=v[num1]-num1;
now=v[num1]+1;
}
else{
ch2++;
num2+=i;
num1=p[num2]-num2;
now=p[num2]+1;
}
}
if(ch1==ch2)flag=0;//平局
if(ch1>ch2&&a[n]!=1)flag=0;//如果a赢但是最后一回合不是a赢
if(ch1<ch2&&a[n]!=2)flag=0;//同上
if(flag){
e[++ans].d=max(ch1,ch2);
e[ans].t=i;
}
}
sort(e+1,e+1+ans);
printf("%d\n",ans);
for(i=1;i<=ans;i++)printf("%d %d\n",e[i].d,e[i].t);
return 0;
}