CF #302 div2

来源:互联网 发布:便宜质量好的淘宝店 编辑:程序博客网 时间:2024/06/14 01:32

A:

题意:

给一个数字n和字符串str,问能否将这个字符串分n段,要求每段的首字母都不相同。

输出这些段。

解析:

找不一样的开头一直往下找到k个就好了,找不到就NO。

代码:

#include <iostream>#include <cstdio>#include <cstdlib>#include <algorithm>#include <cstring>#include <string>#include <cmath>#include <stack>#include <vector>#include <queue>#include <map>#include <climits>#include <cassert>#define LL long longusing namespace std;const int maxn = 1000 + 10;const int inf = 0x3f3f3f3f;const double eps = 1e-8;const double pi = acos(-1.0);const double ee = exp(1.0);int main(){#ifdef LOCAL    freopen("in.txt", "r", stdin);#endif // LOCAL    int k = 0;    scanf("%d", &k);    char str[110];    int pos[30];    scanf("%s", str);    if (k == 1)    {        printf("YES\n");        printf("%s\n", str);    }    else    {        int len = strlen(str);        int cnt = 0;        bool vis[30];        memset(vis, false, sizeof(vis));        vis[str[0] - 'a'] = true;        pos[cnt++] = 0;        bool flag = false;        for (int i = 1; i <= len; i++)        {            if (cnt >= k)            {                pos[cnt++] = len;                flag = true;                break;            }            if (i == len)                break;            if (!vis[str[i] - 'a'])            {                vis[str[i] - 'a'] = true;                pos[cnt++] = i;            }        }        if (flag)        {            printf("YES\n");            for (int i = 1; i < cnt; i++)            {                for (int j = pos[i - 1]; j < pos[i]; j++)                {                    printf("%c", str[j]);                }                printf("\n");            }        }        else        {            printf("NO\n");        }    }    return 0;}

B:

题意:

给一个要构造的n*n的矩阵,然后给一个联通块个数k。

构造一个的n*n矩阵要求由L构成的连通块为个数为k,余下部分为S。

解析:

想起刚开始做CF的时候那题黑白棋,直接奇偶奇偶构造就好了。

代码:

#include <iostream>#include <cstdio>#include <cstdlib>#include <algorithm>#include <cstring>#include <string>#include <cmath>#include <stack>#include <vector>#include <queue>#include <map>#include <climits>#include <cassert>#define LL long longusing namespace std;const int maxn = 1000 + 10;const int inf = 0x3f3f3f3f;const double eps = 1e-8;const double pi = acos(-1.0);const double ee = exp(1.0);int main(){#ifdef LOCAL    freopen("in.txt", "r", stdin);#endif // LOCAL    int n, k;    scanf("%d%d", &n, &k);    int sum = ceil(n * n / 2.0);    if (sum < k)    {        printf("NO\n");    }    else    {        printf("YES\n");        int cnt = 0;        int sx = 0, sy = 0;        for (int i = 0; i < n; i++)        {            for (int j = 0; j < n; j++)            {                if (cnt == k)                {                    printf("S");                    continue;                }                if (i % 2 == 0)                {                    if (j % 2 == 0)                    {                        printf("L");                        cnt++;                    }                    else                    {                        printf("S");                    }                }                else                {                    if (j % 2)                    {                        printf("L");                        cnt++;                    }                    else                    {                        printf("S");                    }                }            }            printf("\n");        }    }    return 0;}

C:

题意:

n个人写m行代码,第i个人写出的代码有ai个bug。

求m行代码出现了b个bug有多少种组合的方法,程序猿必须是按顺序上来写代码,并且下去的就不能再回来。

解析:

dp[ j ] [ k ] 表示第 j 行代码出现 k 个bug时候的组合数。

对于每个ai:

dp [ j ] [ k ]  += dp[ j - 1 ] [ k - a ] 。

有点像硬币凑数的dp,反正想不出来。。T T

代码:

#include <iostream>#include <cstdio>#include <cstdlib>#include <algorithm>#include <cstring>#include <string>#include <cmath>#include <stack>#include <vector>#include <queue>#include <map>#include <climits>#include <cassert>#define LL long longusing namespace std;const int maxn = 500 + 10;const int inf = 0x3f3f3f3f;const double eps = 1e-8;const double pi = acos(-1.0);const double ee = exp(1.0);int dp[maxn][maxn];int main(){#ifdef LOCAL    freopen("in.txt", "r", stdin);#endif // LOCAL    int n, m, b, mod;    scanf("%d%d%d%d", &n, &m, &b, &mod);    for (int i = 0; i <= b; i++)        dp[0][i] = 1;    for (int i = 0; i < n; i++)    {        int a;        scanf("%d", &a);        for (int j = 1; j <= m; j++)        {            for (int k = a; k <= b; k++)            {                dp[j][k] = (dp[j][k] + dp[j - 1][k - a]) % mod;            }        }    }    printf("%d\n", dp[m][b]);    return 0;}

D:

题意:

给一张图,图之间的权值为1个小时。

求一对从一个城市到另一个城市能去掉的路最多有多少条。

解析:

转来转去的。

先用bfs算出两个点之间的最短路,然后两条图会像><图形一样来枚举最短的经过的点数。

枚举的时候还要注意其中一个起点和终点反向也能产生一组枚举。

反正我是想不到啊。。。

代码:

#include <iostream>#include <cstdio>#include <cstdlib>#include <algorithm>#include <cstring>#include <string>#include <cmath>#include <stack>#include <vector>#include <queue>#include <map>#include <climits>#include <cassert>#define LL long longusing namespace std;const int maxn = 3000 + 10;const int inf = 0x3f3f3f3f;const double eps = 1e-8;const double pi = acos(-1.0);const double ee = exp(1.0);int step[maxn][maxn];vector<int> g[maxn];int n, m;void bfs(int s){    queue<int> q;    q.push(s);    step[s][s] = 0;    while (!q.empty())    {        int now = q.front();        q.pop();        for (int i = 0; i < g[now].size(); i++)        {            int to = g[now][i];            if (step[s][to] == -1)            {                step[s][to] = step[s][now] + 1;                q.push(to);            }        }    }}int main(){#ifdef LOCAL    freopen("in.txt", "r", stdin);#endif // LOCAL    memset(step, -1, sizeof(step));    scanf("%d%d", &n, &m);    for (int i = 0; i < m; i++)    {        int fr, to;        scanf("%d%d", &fr, &to);        fr--, to--;        g[fr].push_back(to);        g[to].push_back(fr);    }    for (int i = 0; i < n; i++)    {        bfs(i);    }    int s0, s1, t0, t1, l0, l1;    scanf("%d%d%d%d%d%d", &s0, &t0, &l0, &s1, &t1, &l1);    s0--, s1--, t0--, t1--;    int ans = m + 1;    for (int gggggg = 0; gggggg < 2; gggggg++)    {        int t = s0;        s0 = t0;        t0 = t;        for (int i = 0; i < n; i++)        {            for (int j = 0; j < n; j++)            {                int v0 = step[s0][i] + step[i][j] + step[j][t0];                int v1 = step[s1][i] + step[i][j] + step[j][t1];                if (v0 <= l0 && v1 <= l1)                {                    ans = min(ans, v0 + v1 - step[i][j]);                }            }        }    }    if (step[s0][t0] <= l0 && step[s1][t1] <= l1)    {        ans = min(ans, step[s0][t0] + step[s1][t1]);    }    if (m < ans)        ans = -1;    else        ans = m - ans;    printf("%d\n", ans);    return 0;}


0 0