首页 > 代码库 > Codeforces 496D Tennis Game 枚举+二分
Codeforces 496D Tennis Game 枚举+二分
给定n场比赛。
下面n个数字:表示该场是1获胜还是2获胜。
1、胜利者获得一分。
2、若已经决出整个赛季的胜负则比赛不会继续。
3、设要赢得这个赛季需要赢有s局,每局先获得t分的选手胜利。
问:
找出所有的(s,t)组合使得给定的n场比赛记录合法。
输出要排序。
枚举t。
a数组存第一个人赢的哪些场次。
b数组存第二个人赢的哪些场次。
设赢t分为一句。则判断 第一个人再赢t分是第几场,第二个人再赢t分是第几场。
显然先赢得t分的人赢了这场。
这样同时跑2个人的场数。
复杂度:
设要赢的分数为i, 则这个数组最多枚举 n/i次
i = [1, n]
所以复杂度 = n/1 + n/2 + ··· + n/n = nln(n+1);
其中有个二分。总复杂度是 O( n * ln(n+1) * log n);
[cpp] view plaincopy
- import java.util.ArrayList;
- import java.util.Collections;
- import java.util.List;
- import java.util.Scanner;
- public class Main {
- class Ans implements Comparable<Ans>{
- int s, t;
- public Ans(int a, int b){
- s = a; t = b;
- }
- public int compareTo(Ans o){
- if(s != o.s)return Integer.compare(s, o.s);
- return Integer.compare(t, o.t);
- }
- }
- static int N = 100050;
- int[] a = new int[N], b = new int[N], w = new int[N];
- int at, bt, n;
- ArrayList<Ans> ans = new ArrayList<>();
- void init(){
- n = cin.nextInt();
- for(int i = 1; i <= n; i++)
- w[i] = cin.nextInt();
- at = bt = 0;
- a[at++] = 0; b[bt++] = 0;
- for(int i = 1; i <= n; i++)
- {
- if(w[i]==1)
- a[at++] = i;
- else
- b[bt++] = i;
- }
- at--; bt--;
- ans.clear();
- }
- void add(int x, int y){
- Ans tmp = new Ans(x, y);
- ans.add(tmp);
- }
- void work(int x){
- int na = 0, nb = 0;
- int siza = 0, sizb = 0;
- // System.out.println(x+":"+at+" "+bt);
- while(true){
- if(na == at && nb == bt)break;
- if(na+x > at && nb+x > bt)return ;
- /* if(na+x > at)
- {
- if(nb+x == bt){
- sizb++; break ;
- }
- return ;
- }
- if(nb+x > bt)
- {
- if(na+x == at){
- siza++; break ;
- }
- return ;
- }/**/
- if( na+x<=at &&(nb+x>bt || a[na+x] < b[nb+x]))
- {
- siza++;
- na += x;
- int L = 0, R = bt, pos = 0;
- while(L <= R)
- {
- int mid = (L+R)>>1;
- if(b[mid] < a[na])
- {
- pos = mid;
- L = mid+1;
- }
- else
- R = mid-1;
- }
- nb = pos;
- }
- else if(nb+x <= bt)
- {
- sizb++;
- nb += x;
- int L = 0, R = at, pos = 0;
- while(L <= R)
- {
- int mid = (L+R)>>1;
- if(a[mid] < b[nb])
- {
- pos = mid;
- L = mid+1;
- }
- else
- R = mid-1;
- }
- na = pos;
- }
- else return;
- // System.out.println("["+na+" "+nb+"]"+"{"+siza+" "+sizb+"}");
- }/**/
- // System.out.println("last:"+siza+" "+sizb);
- if(siza == sizb)return;
- if(siza>sizb && w[n] == 1)
- add(siza, x);
- else if(siza<sizb && w[n] == 2)
- add(sizb, x);
- }
- public void work(){
- init();
- // int aaa = 0; if(aaa<=0){System.out.println("debug"); return ;}
- for(int i = 1; i <= n; i++)
- work(i);
- System.out.println(ans.size());
- Collections.sort(ans);
- for(int i = 0; i < ans.size(); i++)
- System.out.println(ans.get(i).s+" "+ans.get(i).t);
- }
- Main() {
- cin = new Scanner(System.in);
- }
- public static void main(String[] args) {
- Main e = new Main();
- e.work();
- }
- public Scanner cin;
- }
Codeforces 496D Tennis Game 枚举+二分
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。