Codeforces Round #302 (Div. 2) A B C

Codeforces Round #302 (Div. 2)

 

A. Set of Strings

字符串 q 被称为 "beautiful" 当且仅当 q 可以被拆分成 k 个子串 (s1, s2, s3, ... , sk) 并且任意两个字串满足首字母不一样。

直接模拟,对 q 的每个字符进行判断,如果该字符在之前没有出现过,那么从它开始就可以组成一个新的字符串,并且计数,如果到了k 了则把之后的都归为一个字符串。

#include <cstring>
#include <iostream>
using namespace std;

char ans[30][100];

int main () {
    int n;
    string s;
    cin >> n >> s;

    int _n = n;

    int vis[26] = {0};

    int k = 0;

    for (int i=0; i<s.size(); i++) {
        if (vis[s[i] - 'a'] == 0) {

            ans[n][k++] = '';

            n--;
            vis[s[i] - 'a'] = 1;

            k = 0;
        }

        ans[n][k++] = s[i];

        if (n == 0) {
            int j ;
            for (j=i+1; j<s.size(); j++) {
                ans[n][k++] = s[j];
            }
            ans[n][k++] = '';
            break;
        }
    }

    if (n == 0) {
        cout << "YES" << endl;

        for (int i=_n-1; i>=0; i--) {
            cout << ans[i] << endl;
        }
    }
    else {
        cout << "NO" << endl;
    }
    return 0;
}
View Code

B. Sea and Islands

问在一个n*n的海域里面是否可以有k个小岛。小岛的定义是岛上的所有点都连在一起,点只有四个方向连在一起。

要尽可能的安排下最多的岛屿,那就得让每个小岛要最小,所以就一个点好吧。问题变成的在n*n的方格里面安排k个方格,并使其不相领。(这题的题意说的真难懂)

#include <iostream>
using namespace std;

char s[101][101];

int main () {
    int n;
    int k;
        
    cin >> n >> k;

    for (int i=0; i<n; i++) {
        for (int j=0; j<n; j++) {
            s[i][j] = 'S';
        }
    }

    int cnt = 0;
    for (int i=0; i<n; i++) {
        for (int j=0; j<n; j++) {
            if (cnt == k) continue;
            if (i%2 == j%2) {
                s[i][j] = 'L';
                cnt++;
            }
        }
    }


    if (cnt == k) {
        cout << "YES" << endl;
        for (int i=0; i<n; i++) {
            for (int j=0; j<n; j++) {
                cout << s[i][j] ;
            }
            cout << endl;
        }
    } else {
        cout << "NO" << endl;
    }
    
    return 0;
}
View Code

C. Writing Code

安排n个人写m行代码,每个人每行会出a[i]个bug,求最多出现b个bug的方案数。

一个二维的完全背包,每个人有两个状态:写j行代码出k个bug

dp[i][j][k] 前i个程序员写钱j行出现k个bug的方案数。

dp[i][j][k] = dp[i][j-1][k-a[i]] + dp[i-1][j][k];

注意这里数组会超内存,需要用滚动数组。

#include <iostream>
using namespace std;

int n, m, b;
long long mod;

long long a[505];

long long dp[2][505][505];

int main () {

    cin >> n >> m >> b >> mod;

    for (int i=1; i<=n; i++) {
        cin >> a[i];
    }

    for (int i=1; i<=n; i++) dp[i % 2][0][0] = 1L;

    for (int i=1; i<=n; i++) {
        for(int j=1; j<=m; j++) {
            for (int k=0; k<=b; k++) {
                if (k < a[i]) dp[i % 2][j][k] = dp[(i-1) % 2][j][k] % mod;
                else dp[i % 2][j][k] = (dp[i % 2][j-1][k - a[i]] + dp[(i-1) % 2][j][k]) % mod;
            }
        }
    }

    long long ans = 0;

    for (int i=0; i<=b; i++) {
        ans = (ans + dp[n % 2][m][i]) % mod;
    }

    cout << ans % mod << endl;

    return 0;
}
View Code
原文地址:https://www.cnblogs.com/xuelanghu/p/4488936.html