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

畫船聽雨發表於2015-01-01

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

#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

#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>


相關文章