码迷,mamicode.com
首页 > 其他好文 > 详细

Codeforces Round #283 (Div. 2) D,E

时间:2015-01-01 16:04:45      阅读:201      评论:0      收藏:0      [点我收藏+]

标签:

D:

题目大意:两个人进行比赛,我们只知道进行了N局比赛的结果,N局之后有一个人赢得了最终的比赛。1代表第一个人赢,2代表第二个人赢。给你他们的输赢情况,让你求出来怎么安排比赛才能得到这种情况,输出时,先按S排序,如果S相同按照T排序。按顺序输出所有的S,T。

思路:我们可以预处理出来在第几的位置某个人赢了x场。

比如:

8
2 1 2 1 1 1 1 1

我们需要枚举赢k场比赛算赢了一小场,注意最后赢的人一定必须是这一局的胜利者。

枚举k之后我们从0开始向后找比如k = 2, xpos代表1赢k场的位置,ypos代表2赢k场的位置。我们找到xpos = 4,ypos = 3,所以如果赢两次算赢一小局的话,2赢下了第一小局。之后2要找赢的两场之后的位置就是sum2=y+k的位置,此时没有,1要找1+k的位置(因为在2赢下一小局的时候1的有一小节是不再被带到下一小局的,所以他如果赢的下一小局的话,就要找到x(到胜负确定的位置时,已经有几小节1结束了)+k(下一次要赢的次数)的位置)。此时xpos = 5,依此类推下去。。。但是需要注意的是在最后一次的比赛的时候1要解决这一小局的比赛,但是k=2时,显然1结局不了最后一局,所以k = 2,不满足条件。

这里找到下一次x+k或者y+k的位置是可以用二分枚举前缀和,也可以hash处理出来所有的和,O(1)的寻找。

D. Tennis Game
time limit per test
2 seconds
memory limit per test
256 megabytes
input
standard input
output
standard output

Petya and Gena love playing table tennis. A single match is played according to the following rules: a match consists of multiple sets, each set consists of multiple serves. Each serve is won by one of the players, this player scores one point. As soon as one of the players scorest points, he wins the set; then the next set starts and scores of both players are being set to 0. As soon as one of the players wins the total of s sets, he wins the match and the match is over. Here s and t are some positive integer numbers.

To spice it up, Petya and Gena choose new numbers s and t before every match. Besides, for the sake of history they keep a record of each match: that is, for each serve they write down the winner. Serve winners are recorded in the chronological order. In a record the set is over as soon as one of the players scores t points and the match is over as soon as one of the players wins s sets.

Petya and Gena have found a record of an old match. Unfortunately, the sequence of serves in the record isn‘t divided into sets and numbers s and t for the given match are also lost. The players now wonder what values of s and t might be. Can you determine all the possible options?

Input

The first line contains a single integer n — the length of the sequence of games (1?≤?n?≤?105).

The second line contains n space-separated integers ai. If ai?=?1, then the i-th serve was won by Petya, if ai?=?2, then the i-th serve was won by Gena.

It is not guaranteed that at least one option for numbers s and t corresponds to the given record.

Output

In the first line print a single number k — the number of options for numbers s and t.

In each of the following k lines print two integers si and ti — the option for numbers s and t. Print the options in the order of increasing si, and for equal si — in the order of increasing ti.

Sample test(s)
input
5
1 2 1 2 1
output
2
1 3
3 1
input
4
1 1 1 1
output
3
1 4
2 2
4 1
input
4
1 2 1 2
output
0
input
8
2 1 2 1 1 1 1 1
output
3
1 6
2 3
6 1

<span style="font-size:18px;">#include <algorithm>
#include <iostream>
#include <stdlib.h>
#include <string.h>
#include <iomanip>
#include <stdio.h>
#include <string>
#include <queue>
#include <cmath>
#include <stack>
#include <time.h>
#include <map>
#include <set>
#define eps 1e-8
#define M 1000100
#define LL long long
//#define LL long long
#define INF 0x3f3f3f
#define PI 3.1415926535898
#define read() freopen("data1.in", "r", stdin)
#define write() freopen("data1.out", "w", stdout);








const int maxn = 200010;


using namespace std;




int sum1[maxn];
int sum2[maxn];




struct node
{
    int sum, pos;
    int flag;
};


node f[maxn], p[maxn];








struct N
{
    int x, y;
} fx[maxn];




bool cmp(N a, N b)
{
    if(a.x == b.x) return a.y < b.y;
    return a.x < b.x;
}


int num[maxn];


int main()
{
    int n;
    while(cin >>n)
    {
        for(int i = 1; i <= n; i++) scanf("%d",&num[i]);
        int cnt = 0;
        sum1[0] = 0;
        sum2[0] = 0;
        for(int i = 1; i <= n; i++)
        {
            f[i].flag = p[i].flag = 0;
            f[i].pos = p[i].pos = 0;
            if(num[i] == 1)
            {
                sum1[i] = sum1[i-1]+1;
                sum2[i] = sum2[i-1];
                continue;
            }
            sum1[i] = sum1[i-1];
            sum2[i] = sum2[i-1]+1;
        }
        for(int i = n; i >= 1; i--)
        {
            f[sum1[i]].pos = i;
            f[sum1[i]].sum = sum1[i];
            f[sum1[i]].flag = 1;


            p[sum2[i]].pos = i;
            p[sum2[i]].sum = sum2[i];
            p[sum2[i]].flag = 1;
        }
        ///for(int i = 1; i <= n; i++) cout<<num[n]<<endl;
        for(int i = 1; i <= n; i++)
        {
            int x = 0;
            int y = 0;
            int xsum1 = 0;
            int xsum2 = 0;
            int xx = 0, yy = 0;
            int xflag = 0;
            while(x < n && y < n)
            {
                ///cout<<x<<" "<<y<<endl;
                int xpos = 0;
                int ypos = 0;
                if(f[x+i].flag) xpos = f[x+i].pos;
                if(p[y+i].flag) ypos = p[y+i].pos;
                if(!xpos && !ypos) break;
                if(xpos && ypos)
                {
                    if(xpos < ypos)
                    {
                        xsum1++;
                        x = sum1[xpos];
                        y = sum2[xpos];
                        xx = xpos;
                    }
                    else
                    {
                        xsum2++;
                        x = sum1[ypos];
                        y = sum2[ypos];
                        xx = ypos;
                    }
                }
                else if(xpos)
                {
                    xsum1++;
                    x = sum1[xpos];
                    y = sum2[xpos];
                    xx = xpos;
                }
                else if(ypos)
                {
                    xsum2++;
                    x = sum1[ypos];
                    y = sum2[ypos];
                    xx = ypos;
                }
            }
            if(xflag) continue;
            if(xx != n ) continue;
            if(xsum1 > xsum2 && (num[n] == 1))
            {
                fx[cnt].x = xsum1;
                fx[cnt++].y = i;
            }
            else if(xsum2 > xsum1 && (num[n] == 2))
            {
                fx[cnt].x = xsum2;
                fx[cnt++].y = i;
            }
        }
        sort(fx, fx+cnt, cmp);
        cout<<cnt<<endl;
        for(int i = 0; i < cnt; i++) cout<<fx[i].x<<" "<<fx[i].y<<endl;
    }
    return 0;
}
</span>

E:和上海区域赛的题目好像,当时慢慢的都是泪啊,sad。。。

整体来说就是一个按照边界排序后的贪心,需要用到STL。

题目大意:每个人都有一个音域,而每个乐队对音域的要求不一样,每个乐队还有一个人数限制,让你把所有的人都安排到乐队当中求,如果安排不下输出“NO”否则输出“YES”,并且输出每个人属于哪个乐队。

思路:人的声音音域,和乐队的要求按照右边r排序,然后枚举每个乐队,把符合的人都送进set里面去,然后找k次,二分set里面的左边l,如果满足l1 >= l2的话说明包含在里面就记录一下然后从set里面丢出来。

E. Distributing Parts
time limit per test
2 seconds
memory limit per test
256 megabytes
input
standard input
output
standard output

You are an assistant director in a new musical play. The play consists of n musical parts, each part must be performed by exactly one actor. After the casting the director chose m actors who can take part in the play. Your task is to assign the parts to actors. However, there are several limitations.

First, each actor has a certain voice range and there are some parts that he cannot sing. Formally, there are two integers for each actor, ciand di (ci?≤?di) — the pitch of the lowest and the highest note that the actor can sing. There also are two integers for each part — aj and bj(aj?≤?bj) — the pitch of the lowest and the highest notes that are present in the part. The i-th actor can perform the j-th part if and only if ci?≤?aj?≤?bj?≤?di, i.e. each note of the part is in the actor‘s voice range.

According to the contract, the i-th actor can perform at most ki parts. Besides, you are allowed not to give any part to some actors (then they take part in crowd scenes).

The rehearsal starts in two hours and you need to do the assignment quickly!

Input

The first line contains a single integer n — the number of parts in the play (1?≤?n?≤?105).

Next n lines contain two space-separated integers each, aj and bj — the range of notes for the j-th part (1?≤?aj?≤?bj?≤?109).

The next line contains a single integer m — the number of actors (1?≤?m?≤?105).

Next m lines contain three space-separated integers each, cidi and ki — the range of the i-th actor and the number of parts that he can perform (1?≤?ci?≤?di?≤?1091?≤?ki?≤?109).

Output

If there is an assignment that meets all the criteria aboce, print a single word "YES" (without the quotes) in the first line.

In the next line print n space-separated integers. The i-th integer should be the number of the actor who should perform the i-th part. If there are multiple correct assignments, print any of them.

If there is no correct assignment, print a single word "NO" (without the quotes).

Sample test(s)
input
3
1 3
2 4
3 5
2
1 4 2
2 5 1
output
YES
1 1 2
input
3
1 3
2 4
3 5
2
1 3 2
2 5 1
output
NO

<span style="font-size:18px;">#include <algorithm>
#include <iostream>
#include <stdlib.h>
#include <string.h>
#include <iomanip>
#include <stdio.h>
#include <string>
#include <queue>
#include <cmath>
#include <stack>
#include <time.h>
#include <map>
#include <set>
#define eps 1e-8
#define M 1000100
#define LL long long
//#define LL long long
#define INF 0x3f3f3f
#define PI 3.1415926535898
#define read() freopen("data1.in", "r", stdin)
#define write() freopen("data1.out", "w", stdout);




const int maxn = 200010;

using namespace std;


struct node
{
    LL l, r, k;
    LL pos, ans;
    bool operator < (const node & b) const
    {
        if(r == b.r) return l < b.l;
        return r < b.r;
    }
};

node f[maxn], p[maxn];

bool cmp(node a, node b)
{
    return a.pos < b.pos;
}

struct Point
{
    LL l, r, pos;
    bool operator < (const Point& b) const
    {
        if(l == b.l)
        {
            if(r == b.r) return pos < b.pos;
            return r < b.r;
        }
        return l < b.l;
    }
};

int n, m;


int main()
{
    ios::sync_with_stdio(false);
    while(cin >>n)
    {
        for(int i = 0; i < n; i++)
        {
            cin >>f[i].l>>f[i].r;
            f[i].pos = i;
        }
        cin >>m;
        for(int i = 0; i < m; i++)
        {
            cin >>p[i].l>>p[i].r>>p[i].k;
            p[i].pos = i;
        }
        sort(f, f+n);
        sort(p, p+m);
        ///for(int i = 0; i < m; i++) cout<<p[i].l<<" "<<p[i].r<<endl;
        set<Point> s;
        int cnt = n;
        for(int i = 0, j = 0; i < m; i++)
        {
            while(j < n && f[j].r <= p[i].r)
            {
                s.insert((Point){f[j].l, f[j].r, j});
                j++;
            }
            for(int sj = 0; sj < p[i].k; sj++)
            {
                set< Point >::iterator it;
                it = s.lower_bound((Point){p[i].l, 0, 0});
                if(it == s.end()) break;
                f[it->pos].ans = p[i].pos+1;
                s.erase(it);
                cnt--;
            }
        }
        if(s.size()!=0 || cnt)
        {
            cout<<"NO"<<endl;
            continue;
        }
        sort(f, f+n, cmp);
        cout<<"YES"<<endl;
        for(int i = 0; i < n-1; i++) cout<<f[i].ans<<" ";
        cout<<f[n-1].ans<<endl;
    }
    return 0;
}
</span>


Codeforces Round #283 (Div. 2) D,E

标签:

原文地址:http://blog.csdn.net/xu12110501127/article/details/42319127

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!