CF264A Escape from Stones

题意

松鼠bored在看小马,现在他要逃避掉下来的石头,石头总是落在bored所在的区间的中间。他有两种选择,一种是向左'l',使区间右端点变为原来的区间中间,一种是向右'r',使区间左端点变为原来的区间中间。bored已经想好了自己的行动路线,为了让他可以继续看小马,请你告诉他下落石头从左到右的编号。

Solution

我们考虑,当石头下落到区间的中间时,松鼠如果向左移动,那么石头就在现在区间的右端点,接下来不管怎么移动,剩下的石头都会在这个石头的左边。松鼠如果向右移动,那么石头就这现在区间的左端点,因为松鼠只能在这个石头的右面移动,所以剩下的石头都在这个石头的右边,可以直接输出。

然后想一下向左移动时的石头咋办,发现向左时掉落的石头,掉的越早,位置越往后即输出的时间越晚,所以我们可以拿 (dfs) 模拟过程,或者拿栈存储向左掉落的石头,或者拿双端队列存储所有石头。

代码

#include<bits/stdc++.h>

using namespace std;
const int N=1e6+10;
char a[N];

int main(){
    scanf("%s",a+1);
    int len=strlen(a+1);
    stack<int> rk;
    for(int i=1;i<=len;i++){
        if(a[i]=='l') rk.push(i);
        else printf("%d
",i);
    }
    while(!rk.empty()){
        printf("%d
",rk.top());
        rk.pop();
    }
    return 0;
}

dfs

#include<bits/stdc++.h>

using namespace std;
const int N=1e6+10;
char a[N];
int n;

void dfs(int st){
    if(st==n) return ;
    if(a[st]=='l'){
        dfs(st+1);printf("%d
",st+1);
    }
    if(a[st]=='r'){
        printf("%d
",st+1);dfs(st+1);
    }
}

int main(){
    while(scanf("%s",a)!=EOF){
        n=strlen(a);
        dfs(0);
    }
    return 0;
}

双端对列

#include<bits/stdc++.h>

using namespace std;
const int N=1e6+10;
int dq[N];
char a[N];

int main(){
    scanf("%s",a+1);
    int len=strlen(a+1);
    int st=1,ed=len;
    for(int i=1;i<=len;i++){
        if(a[i]=='l'){
            dq[st]=i;
            st++;
        }
        if(a[i]=='r'){
            dq[ed]=i;
            ed--;
        }
    }
    for(int i=len;i>=1;i--)
        printf("%d
",dq[i]);
}
原文地址:https://www.cnblogs.com/jasony/p/13817497.html