Codeforces Round #552 (Div. 3) E C++

题目:

  

E. Two Teams

time limit per test

2 seconds

memory limit per test

256 megabytes

input

standard input

output

standard output

There are nn students standing in a row. Two coaches are forming two teams — the first coach chooses the first team and the second coach chooses the second team.

The ii-th student has integer programming skill aiai. All programming skills are distinct and between 11 and nn, inclusive.

Firstly, the first coach will choose the student with maximum programming skill among all students not taken into any team, and kk closest students to the left of him and kk closest students to the right of him (if there are less than kk students to the left or to the right, all of them will be chosen). All students that are chosen leave the row and join the first team. Secondly, the second coach will make the same move (but all students chosen by him join the second team). Then again the first coach will make such move, and so on. This repeats until the row becomes empty (i. e. the process ends when each student becomes to some team).

Your problem is to determine which students will be taken into the first team and which students will be taken into the second team.

Input

The first line of the input contains two integers nn and kk (1≤k≤n≤2⋅1051≤k≤n≤2⋅105) — the number of students and the value determining the range of chosen students during each move, respectively.

The second line of the input contains nn integers a1,a2,…,ana1,a2,…,an (1≤ai≤n1≤ai≤n), where aiai is the programming skill of the ii-th student. It is guaranteed that all programming skills are distinct.

Output

Print a string of nn characters; ii-th character should be 1 if ii-th student joins the first team, or 2 otherwise.

思路:

  模拟。

  第一次找出最大的数字,放入第一队,然后将这个人左边和右边的k个人也放入第一队(已经有队伍的人就除外咯)。

  第二次也是上述步骤,然后放入第二队。

  重复上述步骤。

  (注意这n个人的编码能力为1~n的一个全排列。)

超时代码!!!!

 

#include<bits/stdc++.h>
using namespace std;
int n,k,d[200010],t=0;
int a[200010],b[200010];
int main ()
{
    cin>>n>>k;
    int i;
    for(i=1;i<=n;i++)
        {
            scanf("%d",&a[i]);
            b[a[i]]=i;
        }
    for(int h=n;h>=1;h--){
            i=b[h];
            int flag=t%2+1;
        if(d[i]==0){
            d[i]=flag;
            int j=i+1,cnt=0;
            while(j<=n){
                if(d[j]) {
                    j++;
                    continue;
                }
                cnt++;
                d[j]=flag;
                if(cnt==k) break;
                j++;
            }
            cnt=0;
            j=i-1;
            while(j>=1){
                    if(d[j]) {
                    j--;
                    continue;
                }
                cnt++;
                d[j]=flag;
                if(cnt==k) break;
                j--;
            }
            t++;
        }
    }
    for(i=1;i<=n;i++) cout<<d[i];
   return 0;
}
}

改进:将已经有队伍的人删除。(借鉴了大佬的解法)AC代码:  
#include<bits/stdc++.h>
using namespace std;
int n,k,d[200010],t=0;
int a[200010],b[200010],l[200010],r[200010];
void eraser(int x)
{
    l[r[x]]=l[x];
    r[l[x]]=r[x];
}
int main ()
{
    cin>>n>>k;
    int i;
    for(i=1;i<=n;i++)
        {
            scanf("%d",&a[i]);
            b[a[i]]=i;
            l[i]=i-1;
            r[i]=i+1;
        }
    for(int h=n;h>=1;h--){
            i=b[h];
            int flag=t%2+1;
        if(d[i]==0){
            eraser(i);
            d[i]=flag;
            int j=r[i],cnt=0;
            while(j<=n){
                if(d[j]) {
                    j++;
                    continue;
                }
                cnt++;
                d[j]=flag;
                eraser(j);
                if(cnt==k) break;
                j++;
            }
            cnt=0;
            j=l[i];
            while(j>=1){
                    if(d[j]) {
                    j--;
                    continue;
                }
                cnt++;
                d[j]=flag;
                eraser(j);
                if(cnt==k) break;
                j--;
            }
            t++;
        }
    }
    for(i=1;i<=n;i++) cout<<d[i];
   return 0;
}
 

原文地址:https://www.cnblogs.com/-xyp/p/10742583.html

时间: 2024-08-30 08:29:44

Codeforces Round #552 (Div. 3) E C++的相关文章

Codeforces Round #552 (Div. 3) C题

题目网址:http://codeforces.com/contest/1154/problem/C 题目意思:小猫吃三种食物,A,B,C,一周吃食物的次序是,A,B,C,A,C,B,A,当小猫该天无食物可吃时,就会饿死,现给出a,b,c三个数,表示A,B,C的食物数量, 选择一天开始,问小猫最多可以活到多少天. 题解:首先,在一周时间,A要吃三天,B要吃两天,C要吃两天,先随便选一天开始,当剩下食物不足以撑过一周时停止,再细分剩下的食物数量,看小猫饿 死是经过的最多天数.选择的天数用暴力写即可.

Codeforces Round #552(div.3)

Problem: http://codeforces.com/contest/1154 A: 1 /* basic header */ 2 #include <iostream> 3 #include <cstdio> 4 #include <cstdlib> 5 #include <string> 6 #include <cstring> 7 #include <cmath> 8 #include <cstdint> 9

Codeforces Round #552 (Div. 3) Editorial 1154C - Gourmet Cat

链接:https://codeforces.com/contest/1154/problem/C 题意:一只旅行的小猫在特定的星期里吃特定的食物,一四七a,二六b,三五c,现在给三种食物的数量,问小猫最多能活几天. 思路:先看小猫能活几个整星期,因为a在一个星期里占三天,b和c各占两天,所以取min(a/3,b/2,c/2),然后求剩下的,这个时候就可以枚举日子了,从周一枚举到周日,然后模拟一哈就行了,虽然是个水题但我还是没做粗来 代码: 1 //#include<bits/stdc++.h>

Codeforces Round #552 (Div. 3)-D-Walking Robot-(贪心)

http://codeforces.com/contest/1154/problem/D 解题: 1.无光的时候优先使用太阳能电池. 2.有光的时候 (1)太阳能电池没满电,让它充,使用普通电池 (2)太阳能电池满电,使用太阳能电池 #include<stdio.h> #include<math.h> #include<string.h> #include<algorithm> #include<string> #include<vecto

Codeforces Round #552 (Div. 3)-1154E-Two Teams-(模拟+双指针)

http://codeforces.com/contest/1154/problem/E 解题: 举例n=10,k=1 1,2,10,4,7,6,9,8,5,3 第一次,1队先挑2,10,4这三个人 1,2,10,4,7,6,9,8,5,3 第二次,2队挑6,9,8三个人 1,2,10,4,7,6,9,8,5,3 第三次,1队挑1,7,5三个人 1,2,10,4,7,6,9,8,5,3 第四次,2队挑3一个人 1,2,10,4,7,6,9,8,5,3 显然需要实现的有两点 (1)挑完后的“连接”

Codeforces Round #428 (Div. 2)

Codeforces Round #428 (Div. 2) A    看懂题目意思就知道做了 #include<bits/stdc++.h> using namespace std; #pragma comment(linker, "/STACK:102400000,102400000") #define rep(i,a,b) for (int i=a; i<=b; ++i) #define per(i,b,a) for (int i=b; i>=a; --i

Codeforces Round #424 (Div. 2) D. Office Keys(dp)

题目链接:Codeforces Round #424 (Div. 2) D. Office Keys 题意: 在一条轴上有n个人,和m个钥匙,门在s位置. 现在每个人走单位距离需要单位时间. 每个钥匙只能被一个人拿. 求全部的人拿到钥匙并且走到门的最短时间. 题解: 显然没有交叉的情况,因为如果交叉的话可能不是最优解. 然后考虑dp[i][j]表示第i个人拿了第j把钥匙,然后 dp[i][j]=max(val(i,j),min(dp[i-1][i-1~j]))   val(i,j)表示第i个人拿

Codeforces Round #424 (Div. 2) C. Jury Marks(乱搞)

题目链接:Codeforces Round #424 (Div. 2) C. Jury Marks 题意: 给你一个有n个数序列,现在让你确定一个x,使得x通过挨着加这个序列的每一个数能出现所有给出的k个数. 问合法的x有多少个.题目保证这k个数完全不同. 题解: 显然,要将这n个数求一下前缀和,并且排一下序,这样,能出现的数就可以表示为x+a,x+b,x+c了. 这里 x+a,x+b,x+c是递增的.这里我把这个序列叫做A序列 然后对于给出的k个数,我们也排一下序,这里我把它叫做B序列,如果我

[Codeforces] Round #352 (Div. 2)

人生不止眼前的狗血,还有远方的狗带 A题B题一如既往的丝帛题 A题题意:询问按照12345678910111213...的顺序排列下去第n(n<=10^3)个数是多少 题解:打表,输出 1 #include<bits/stdc++.h> 2 using namespace std; 3 int dig[10],A[1005]; 4 int main(){ 5 int aa=0; 6 for(int i=1;;i++){ 7 int x=i,dd=0; 8 while(x)dig[++dd