codeforces 497B Tennis Game 思维+二分~

链接:http://codeforces.com/problemset/problem/497/B

这种题考察的是基本功。。像我这种基本功为0的喳喳只能卡在这里了。。。

思路:n范围为10^5, 必须找出nlogn的算法才行。枚举t,然后用二分找出解。。巧妙~~ 好题赞一个,虽然不会做~~~

代码:

  

/* ***********************************************
Author        :ltwy
Created Time  :2014年12月18日 星期四 16时28分12秒
File Name     :1.cpp
************************************************ */

#include <stdio.h>
#include <string.h>
#include <iostream>
#include <algorithm>
#include <vector>
#include <queue>
#include <stack>
#include <set>
#include <map>
#include <string>
#include <math.h>
#include <stdlib.h>
#include <time.h>
using namespace std;

int n;
int a[101000];
int sum1[101000];
int sum2[101000];

pair<int, int> p[100100];

int get_next(int s, int st, int ed)
{
    if(sum1[ed] - sum1[st-1] <s && sum2[ed] - sum2[st-1] < s)
        return -1;
    int l = st, r = ed;
    int id = ed;

    while(l <= r)
    {
        int mid = (l+r)>>1;
        if(sum1[mid] - sum1[st-1] < s&& sum2[mid] - sum2[st-1] < s)
        {
            l = mid+1;
        }
        else
        {
            id = mid;
            r = mid -1;
        }
    }
    return id;
}
int main()
{
    //freopen("in.txt","r",stdin);
    //freopen("out.txt","w",stdout);

    scanf("%d", &n);

    for(int i=1; i<=n; i++)
    {
        scanf("%d", &a[i]);
    }

    memset(sum1, 0, sizeof(sum1));
    memset(sum2, 0, sizeof(sum2));

    int T1 = 0, T2 = 0;
    for(int i = 1; i<=n; i++)
    {
        if(a[i] == 1)
            T1++;
        if(a[i] == 2)
            T2++;
        sum1[i] = T1;
        sum2[i] = T2;
    }

    int cnt = 0;
    int W1 = 0;
    int W2 = 0;
    bool flag;
    for(int s=1; s<=n; s++)
    {
        W1 = 0;
        W2 = 0;
        flag = false;
        if(sum1[n] < s && sum2[n] < s)
            break;
        int pos = 1;
        int last = 0;
        while(pos <= n)
        {
            int temp = get_next(s, pos, n);
            if(temp == -1)
            {
                flag = true;
                break;
            }
            if(a[temp] == 1)
            {
                W1++;
                last = 1;
            }
            else
            {
                W2++;
                last = 2;
            }
            pos = temp+1;
        }
        if(flag)
            continue;
        if(W1 == W2)
            continue;
        if(W1 > W2&& last == 2)
            continue;
        if(W2 > W1&& last == 1)
            continue;
        p[cnt++] = make_pair(max(W1, W2), s);
    }

    printf("%d\n", cnt);
    sort(p, p+cnt);
    for(int i=0; i<cnt; i++)
        printf("%d %d\n", p[i].first, p[i].second);
    return 0;
}
时间: 2024-08-26 11:37:04

codeforces 497B 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个人的场数

Codeforces 374D Inna and Sequence 二分+树状数组

题目链接:点击打开链接 给定n个操作,m长的序列a 下面n个数 if(co>=0)则向字符串添加一个co (开始是空字符串) else 删除字符串中有a的下标的字符 直接在序列上搞,简单模拟 #include<stdio.h> #include<iostream> #include<string.h> #include<set> #include<vector> #include<map> #include<math.h&

Codeforces 8D Two Friends 三分+二分+计算几何

题目链接:点击打开链接 题意:点击打开链接 三分house到shop的距离,二分这条斜边到cinema的距离 #include<stdio.h> #include<string.h> #include<iostream> #include<algorithm> #include<math.h> #include<set> #include<queue> #include<vector> #include<

Codeforces 479D Long Jumps(贪心+二分)

题目链接:Codeforces 479D Long Jumps 题目大意:valery是个体育老师,现在他要为学生考跳远,女生标准为x,男生为y,现在一个长为L的刻度尺,有N个刻 度,给定N个刻度,现在为说还需要加几个刻度才能测量x,y这两个长度. 解题思路:因为总共就x,y两个长度,所以最多加两个刻度.所以只要判断不加和加一个的情况即可. 先枚举每个刻度a[i],然后用二分查找一下a[i]+x或者a[i]-x刻度存不存在,同理y.如果x和y都通过判断,那么就是不需 要加刻度. 如果只通过x或只

Codeforces 484B Maximum Value(高效+二分)

题目链接:Codeforces 484B Maximum Value 题目大意:给定一个序列,找到连个数ai和aj,ai%aj尽量大,并且ai≥aj 解题思路:类似于素数筛选法的方式,每次枚举aj,然后枚举k,每次用二分找到小于k?aj并且最大的ai,维护答案,过程中加了一些剪枝. #include <cstdio> #include <cstring> #include <algorithm> using namespace std; const int maxn =

codeforces 735C Tennis Championship(贪心+递推)

Tennis Championship 题目链接:http://codeforces.com/problemset/problem/735/C --每天在线,欢迎留言谈论. 题目大意: 给你一个 n (2≤n≤10^18),代表一共有n位参加比赛的选手. 游戏规则: ①每次比赛,输的选手将离开赛场 ②相互比赛的选手 他们的获胜的次数相差不能超过1(获胜4次的选手只能跟3或5次的选手比赛) 问题:最终赢得比赛的选手,胜场最多能为多少. 思路: 贪心:①选一名选手让他一直获胜且优先让他参加比赛 ②当

Codeforces 825D Suitable Replacement - 贪心 - 二分答案

You are given two strings s and t consisting of small Latin letters, string s can also contain '?' characters. Suitability of string s is calculated by following metric: Any two letters can be swapped positions, these operations can be performed arbi

Codeforces 483B Friends and Presents(二分+数论)

题目链接:Codeforces 483B Friends and Presents 题目大意:要将1~v直间的数分配到两个集合中,第一个集合需要cnt1个数,第二个需要cnt2个数,第一个集合中的数 不能是x的倍数,同理第二个集合不能是y的倍数,两集合元素不能相同,问说v最小可以为多少. 解题思路:这题比第三题要难,想了有一会.二分答案,v,然后判断. 判断的时候只要分别判断集合一,二个数是否满足,但是因为有些数可以被分到两个集合,所以要判断总的可分配个数 是否满足大于cnt1+cnt2,计算总

Codeforces 483B - Friends and Presents - [二分]

题目链接:http://codeforces.com/contest/483 A - Counterexample - [简单构造题] Your friend has recently learned about coprime numbers. A pair of numbers $(a,?b)$ is called coprime if the maximum number that divides both $a$ and $b$ is equal to one. Your friend