【2017 ICPC 沈阳】G.Infinite Fraction Path 暴力优化

题目链接

题意

给出 N 个城市编号为\(0,1,2...N-1\),每个城市都有一个价值 \(val_i\),范围为 \([0,9]\),第 \(i\) 个城市可以去 第 \((i^2+1)\%N\) 个城市。

如果从第 \(i\) 个城市出发,途径\(u_1,u_2,u_3...\) 等城市,那么会得到一个小数 \(0.val_i val_{u_1}val_{u_2}...\)

求出最大的一个小数的前 N 位。

思路

对于每一位肯定选择当前能找到的最大值。

我们就遍历 N 位。
初始,我们把价值最大的城市编号放入到一个vector:now中。

然后遍历 now 中的节点,找到下一位可能取值的最大值的所有编号,更新到 now 中,有个小优化:去除重复的位置。

就这样遍历 N 次即可。

比赛的时候觉得复杂度太高,没敢写。。。

代码

/*
 * @Autor: valk
 * @Date: 2020-08-21 11:06:28
 * @LastEditTime: 2020-10-22 20:46:18
 * @Description: 如果邪恶  是华丽残酷的乐章 它的终场 我会亲手写上 晨曦的光 风干最后一行忧伤 黑色的墨 染上安详
 */
#include <bits/stdc++.h>
#define fuck system("pause")
#define emplace_back push_back
#define pb push_back
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
const int mod = 1e9 + 7;
const int seed = 12289;
const double eps = 1e-6;
const int inf = 0x3f3f3f3f;
const int N = 2e5 + 10;

char str[N];
ll val[N], nxt[N], vis[N];

vector<ll> vec, ans, temp;
ll n;
void solve()
{
    ll maxn = -1;
    for (ll i = 1; i <= n; i++) {
        maxn = max(maxn, val[i]);
    }
    for (ll i = 1; i <= n; i++) {
        if (val[i] == maxn) {
            vec.pb(i);
        }
    }
    for (ll i = 1; i <= n; i++) {
        ans.pb(val[vec[0]]);
        maxn = -1;
        for (ll j = 0; j < vec.size(); j++) {
            maxn = max(maxn, val[nxt[vec[j]]]);
            vis[vec[j]] = 0;
        }
        for (ll j = 0; j < vec.size(); j++) {
            if (val[nxt[vec[j]]] == maxn && !vis[nxt[vec[j]]]) {
                vis[nxt[vec[j]]] = 1;
                temp.pb(nxt[vec[j]]);
            }
        }
        vec = temp, temp.clear();
    }
}
int main()
{
    ll T, cas = 0;
    scanf("%lld", &T);
    while (T--) {
        vec.clear(), ans.clear(), temp.clear();
        memset(vis, 0, sizeof(vis));
        scanf("%lld%s", &n, str + 1);
        for (ll i = 1; i <= n; i++) {
            val[i] = str[i] - '0';
            nxt[i] = 1LL * ((i - 1) * (i - 1) + 1) % n + 1;
        }
        solve();
        printf("Case #%lld: ", ++cas);
        for (ll i = 0; i < ans.size(); i++) {
            printf("%lld", ans[i]);
        }
        printf("\n");
    }
    return 0;
}
posted @ 2020-10-23 10:45  Valk3  阅读(92)  评论(0编辑  收藏  举报