问题 J: Juggling Troupe

问题 J: Juggling Troupe

时间限制: 3 Sec  内存限制: 128 MB

题目描述

At the national centre for computing and advanced circus skills, technical demonstrations by students are strongly encouraged.
A troupe of n novice performers are at this very moment arrayed in a row attempting to put on a juggling show. Unfortunately, none of them are very confident in their craft, and they are struggling. Thus, as soon as an opportunity presents itself, they will try to reduce their part in the performance to make the task easier.
Whenever a juggler has more than one ball in their possession, they will throw one ball to each of their neighbours. In the case that a juggler does not have a neighbour in some direction, they will simply throw the ball offstage instead. Everybody throws their juggling balls simultaneously. The show ends when no juggler has more than one ball.
As a member of the audience, you are not impressed by this performance. However, you do wonder how many balls each of the jugglers will have left at the end of the show.

输入

The input consists of:
• One line with a string s of length n (1 ≤ n ≤ 106 ) over the characters 0, 1 and 2. The ith character in s represents the number of juggling balls initially held by the ith person.

输出

Output a string s of length n over the characters 0 and 1, the ith giving the number of juggling balls the ith person has at the end of the show.

样例输入

12100212

样例输出

10111111





题目大意:

开始时nn个人排成一列,每个人手上有至多两个球,每一轮手里有多于11个球的人扔一个球到左边,扔一个球到右边,如果那个人在最左边或最右边,则直接将球扔掉(即没有人接的球直接扔掉)。每一轮的球是同时扔的,问最后无法再进行时的状态(每一个人手上有多少个球)。



分析:

找规律。发现如果只有一个2时,设2的位置为i,i的左边第一个0的位置为L,i右边第一个0的位置为R,最终的状态为:位置L,R变为1,位置L+R−i变为0,[L,R]的其它位置变为1。
又发现每个2是独立的,即每个2可以不同时扔球,可以分开处理。所以最终的解法就是按照只有一个2的解法解决每个2即可。








AC代码:
#include<bits/stdc++.h>
#define lowbit(x) (x&-x)
#define gcd(a,b) __gcd(a,b)
#define mset(a,x) memset(a,x,sizeof(a))
#define FIN freopen("input","r",stdin)
#define FOUT freopen("output","w",stdout)
const int INF=0x3f3f3f3f;
const double pi=acos(-1.0);
const double eps=1e-6;
const int MAX=1e5+10;
const int mod=1e9+7;
typedef long long ll;
using namespace std;
inline ll lcm(ll a,ll b){return a/gcd(a,b)*b;}
inline ll qpow(ll a,ll b){ll r=1,t=a; while(b){if(b&1)r=(r*t)%mod;b>>=1;t=(t*t)%mod;}return r;}
inline ll inv1(ll b){return qpow(b,mod-2);}
inline ll inv2(ll b){return b==1?1:(mod-mod/b)*inv2(mod%b)%mod;}
inline ll exgcd(ll a,ll b,ll &x,ll &y){if(!b){x=1;y=0;return a;}ll r=exgcd(b,a%b,y,x);y-=(a/b)*x;return r;}
int dir[4][2]={0,1,1,0,0,-1,-1,0};
char str[1000005];
int temp[1000005];
int main (){
    scanf ("%s",str+1);
    int n=strlen(str+1);
    set<int> S;
    int Index=0;
    S.insert(0); S.insert(n+1);
    for (int i=1;i<=n;i++){
        if(str[i]=='0') S.insert(i);
        if(str[i]=='2') temp[Index++]=i;
    }
    for (int i=0;i<Index;i++){
        set<int>::iterator it=S.lower_bound(temp[i]);
        int right=*it;
        int left=*--it;
        if(left!=0) str[left]='1',S.erase(left);
        if(right!=n+1) str[right]='1',S.erase(right);
        str[left+right-temp[i]]='0';
        S.insert(left+right-temp[i]);
        if(str[temp[i]]!='0') str[temp[i]]='1';
    }
    for (int i=1;i<=n;i++)
        if(str[i]=='0') putchar('0');
        else putchar('1');
    putchar('\n');
    return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值