Codeforces Round #650 (Div. 3)

D. Task On The Board

题目大意:

想法:

我们容易想到我们每次按照字符的大小 从大往小去放字符,因为这样可以确保后面放的字符对之前放的字符没有影响。

换句话说:我们每选取了一个“大”的字符 它都会对它之后选取的字符造成影响(因为后面选取的都是“小”的)。也就是说每选取了一个字符,我们需要去看它确定我们后续需要选取的字符是什么(同一轮确定的字符我们要确保它们之间没有影响)

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <cmath>
#include <vector>

#define ll long long
#define ull unsigned long long
#define ls nod<<1
#define rs (nod<<1)+1
#define pii pair<int,int>
#define mp make_pair
#define pb push_back
#define INF 0x3f3f3f3f
#define max(a, b) (a>b?a:b)
#define min(a, b) (a<b?a:b)


const double eps = 1e-8;
const int N = 2e6 + 10;
const ll MOD = 998244353;
const int mlog=20;

int sgn(double a) { return a < -eps ? -1 : a < eps ? 0 : 1; }

using namespace std;

char s[100];
int b[100],vis[2000],num[50],ans[100];

int main() {
    int t;
    scanf("%d",&t);
    while (t--) {
        int n;
        scanf("%s %d",s+1,&n);
        for (int i = 1;i <= n;i++) {
            scanf("%d",&b[i]);
            vis[i] = 0;
        }
        for (int i = 0;i < 26;i++)
            num[i] = 0;
        for (int i = 1;i <= strlen(s+1);i++) {
            num[s[i]-'a']++;
        }
        vector<int> vec;
        int m = n;
        int now = 25;
        while (m) {
            int cnt = 0;
            vector<int> pos;
            for (int i = 1;i <= n;i++) {
                if (vis[i])
                    continue;
                int sum = 0;
                for (auto &to:vec)
                    sum += abs(to-i);
                if (sum == b[i])
                    pos.push_back(i);
            }
            for (auto &to:pos) {
                vis[to] = true;
                cnt++;
                vec.push_back(to);
            }
            while (num[now] < cnt)
                now--;
            m -= cnt;
            for (auto &to:pos)
                ans[to] = (char) (now + 'a');
            now--;
        }
        for (int i = 1;i <= n;i++)
            printf("%c",ans[i]);
        printf("
");
    }
    return 0;
}

E. Necklace Assembly

题目大意:

想法:

首先我们应该想到 k 的因数应该都是满足的  因为是成倍的增长。

然后我们可以发现字符串

s[1] -> s[j + 1]  

s[2] -> s[j + 2]

s[3] -> s[j + 3]

....

s[j - 1] -> s[2 * j - 1]

所以我们可以考虑字符串分成的段数,每段有 j 个字符,这样字符串的长度 = 每段的字符 * 分成的段数。 

并且字符串分成的段数是符合二分的性质的,可以考虑二分。

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <cmath>
#include <vector>

#define ll long long
#define ull unsigned long long
#define ls nod<<1
#define rs (nod<<1)+1
#define pii pair<int,int>
#define mp make_pair
#define pb push_back
#define INF 0x3f3f3f3f
#define max(a, b) (a>b?a:b)
#define min(a, b) (a<b?a:b)


const double eps = 1e-8;
const int N = 2e6 + 10;
const ll MOD = 998244353;
const int mlog=20;

int sgn(double a) { return a < -eps ? -1 : a < eps ? 0 : 1; }

using namespace std;

char s[2010];
int num[30];

bool check(int mid,int v) {
    for (int i = 0;i <= 25;i++) {
        mid -= num[i] / v;
        if (mid <= 0)
            return true;
    }
    return false;
}
int main() {
    int t;
    scanf("%d",&t);
    while (t--) {
        int n,k;
        scanf("%d%d",&n,&k);
        scanf("%s",s+1);
        for (int i = 0;i <= 26;i++)
            num[i] = 0;
        for (int i = 1;i <= n;i++) {
            num[s[i]-'a']++;
        }
        int ans = 0;
        for (int i = 0;i <= 25;i++) {
            ans = max(ans,num[i]);
        }
        vector<int> vec;
        for (int i = 2;i <= k;i++) {
            if (k % i == 0)
                vec.pb(i);
        }
        for (auto &v:vec) {
            int l = 1,r = n / v;
            while (l <= r) {
                int mid = (l + r) >> 1;
                if (check(v,mid)) {
                    ans = max(ans,mid*v);
                    l = mid + 1;
                }
                else
                    r = mid - 1;
            }
        }
        printf("%d
",ans);
    }
    return 0;
}

F1. Flying Sort (Easy Version)

题目大意:

想法:

首先数组a[i]的范围很大,我们需要先对它进行离散化,得到一个 1~n 的数组

然后我们可以发现 我们可以把问题转化为找到一组最长的不需要操作的序列 (因为这些序列不需要调整,其他的调整就可以了)

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <cmath>
#include <vector>

#define ll long long
#define ull unsigned long long
#define ls nod<<1
#define rs (nod<<1)+1
#define pii pair<int,int>
#define mp make_pair
#define pb push_back
#define INF 0x3f3f3f3f
#define max(a, b) (a>b?a:b)
#define min(a, b) (a<b?a:b)


const double eps = 1e-8;
const int maxn = 1e4 + 10;
const ll MOD = 998244353;
const int mlog=20;

int sgn(double a) { return a < -eps ? -1 : a < eps ? 0 : 1; }

using namespace std;


int a[maxn],s[maxn];
int dp[maxn];
int main() {
    ios::sync_with_stdio(false);
    int t;
    cin >> t;
    while (t--) {
        int n;
        cin >> n;
        for (int i = 1;i <= n;i++) {
            cin >> a[i];
            s[i] = a[i];
            dp[i] = 0;
        }
        sort(s+1,s+1+n);
        for (int i = 1;i <= n;i++) {
            a[i] = lower_bound(s+1,s+1+n,a[i]) - s;
        }
        int Max = 1;
        for (int i = 1;i <= n;i++) {
            dp[a[i]] = dp[a[i]-1]+1;
            Max = max(Max,dp[a[i]]);
        }
        cout << n - Max << endl;
    }
    return 0;
}
原文地址:https://www.cnblogs.com/-Ackerman/p/13541071.html