题目链接:点击打开链接
题意:
给定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);
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; }
时间: 2024-10-18 22:49:01