codeforces 733E (数学)

题目链接:点击这里

题意:n个台阶,每个台阶上有上或者下,每经过一次都会改变方向。求从每个台阶出发,从最下方或者最上方走出去的步数

对于每一个开始的台阶,只有他下方的U和他上方的D会影响最后的步数。如果要从下方出去就需要把下面都变成D,同样的,要从上面出去就要把上面都变成U。观察一下发现交换初始台阶上下方的D和U的步数花费就是两者距离的一半,最后加上开始台阶从下方或者上方走出的步数。
trick:结果会爆int

#include <bits/stdc++.h>
#define Clear(x,y) memset (x,y,sizeof(x))
#define FOR(a,b,c) for (int a = b; a <= c; a++)
#define REP(a,b,c) for (int a = b; a >= c; a--)
#define first fi
#define second se
#define pii pair<int, int>
#define pli pair<long long, int>
#define mp make_pair
#define pb push_back
using namespace std;
#define maxn 1000005

char s[maxn];
long long n, sum1, sum2;
long long l[maxn], r[maxn];
vector <long long> ans1, ans2, u, d;

int main () {
    //freopen ("more.in", "r", stdin);
    cin >> n >> s+1;
    l[0] = r[n+1] = 0;
    u.clear (); d.clear ();
    FOR (i, 1, n) {
        l[i] = l[i-1]+(s[i] == 'U');
        if (s[i] == 'U') u.pb (i);
        else d.pb (i);
    }
    REP (i, n, 1) {
        r[i] = r[i+1]+(s[i] == 'D');
    }
    int cut = n+1;
    FOR (i, 1, n) {
        if (l[i-1] < r[i+1] || (l[i-1] == r[i+1] && s[i] == 'D')) continue;
        else {
            cut = i;
            break;
        }
    }
    sum1 = sum2 = 0;
    ans1.clear (); ans2.clear ();
    int i = u.size()-1, j = 0;
    FOR (pos, 1, cut-1) {
        if (s[pos] == 'U') sum1 += pos*2;
        else sum2 -= pos*2;
        sum2 += d[j++]*2; 
        ans1.pb (sum2-sum1+pos);
    }
    sum1 = sum2 = 0;
    REP (pos, n, cut) {
        if (s[pos] == 'D') sum2 += pos*2;
        else if (s[pos] == 'U') sum1 -= pos*2;
        sum1 += u[i--]*2; 
        ans2.pb (sum2-sum1+n-pos+1);
    }
    for (int i = 0; i < ans1.size (); i++) cout << ans1[i] << " ";
    REP (i, ans2.size()-1, 0) {
        cout << ans2[i] << " ";
    } cout << endl;
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值