CSDN竞赛第12期题解

CSDN编程竞赛报名地址:https://edu.csdn.net/contest/detail/25
(请不要删掉此地址)

1. 题目名称:豚鼠排名榜

已知字符A.B,C。每个字符都有自己的权值q。 现不知道权值q,只知道A,B,C的三次比较结果。 要求从小到大输出排序的结果。

        根据题意,可以先找到最大的字符,如果找不到就是无解,找到了就再比较剩下两个字符即可。更一般的做法可以根据大于关系建一个图,用拓扑排序求出排序结果。 

#include <bits/stdc++.h>
using namespace std;
int a[5][5];
int main()
{
    char s[100];
    for (int i = 0; i < 3; ++i)
    {
        scanf("%s", s);
        int x = s[0] - 'A', y = s[2] - 'A';
        int w = s[1] == '<' ? 0 : 1;
        a[x][y] = w;
        a[y][x] = w ^ 1;
    }
    int mx = -1;
    for (int i = 0; i < 3; ++i)
    {
        mx = i;
        for (int j = 0; j < 3; ++j)
        {
            if (j == i)
                continue;
            if (a[i][j] == 0)
            {
                mx = -1;
                break;
            }
        }
        if (mx != -1)
            break;
    }
    if (mx == -1)
        return puts("Impossible"), 0;
    int mx2 = -1, mx3 = -1;
    for (int i = 0; i < 3; ++i)
    {
        mx2 = -1;
        if (i == mx)
            continue;
        for (int j = 0; j < 3; ++j)
        {
            if (j == i || j == mx)
                continue;
            if (a[i][j] == 1)
            {
                mx2 = i;
                mx3 = j;
                break;
            }
        }
        if (mx2 != -1)
            break;
    }
    printf("%c%c%c\n", mx3 + 'A', mx2 + 'A', mx + 'A');
    return 0;
}

2. 题目名称:字符串转换 

已知一个字符串a,b。 字符串b中包含数量不等的特殊符号“.”,“*”(字符串存在没有特殊符号或者全由特殊符号组成的情 况)。 “.”表示该字符可以变成任意字符,“* ”表示该字符的前一个字符可以变成任意多个。 现在我们想知道b可否通过特殊符号变成a。 a* 可以转化为a,aa,aaa,aaaa… 

         动态规划:dp[i][j][k]表示能否让a[1~i]=b[1~j]且b[1~j]的末尾字符为k。

#include <bits/stdc++.h>
using namespace std;
const int maxn = 1010;
char a[maxn], b[maxn];
int dp[2][maxn][26];
int main()
{
    scanf("%s%s", a + 1, b + 1);
    int n = strlen(a + 1), m = strlen(b + 1), t = 0;
    memset(dp, 0x3f, sizeof(dp));
    for (int i = 0; i < 26; ++i)
    {
        dp[0][0][i] = 1;
    }
    for (int i = 1; i <= n; ++i)
    {
        t ^= 1;
        memset(dp[t], 0, sizeof(dp[t]));
        for (int j = 1; j <= m; ++j)
        {
            if (b[j] == '.' || b[j] == a[i])
            {
                dp[t][j][a[i] - 'a'] = *max_element(dp[t ^ 1][j - 1], dp[t ^ 1][j - 1] + 26);
            }
            else if (b[j] == '*')
            {
                dp[t][j][a[i] - 'a'] = dp[t ^ 1][j - 1][a[i] - 'a'];
            }
        }
    }
    int ans = *max_element(dp[t][m], dp[t][m] + 26);
    if (ans)
        puts("yes");
    else
        puts("no");
}

 

3. 题目名称:蚂蚁家族 

小蚂蚁群是一个庞大的群体,在这个蚂蚁群中有n只小蚂蚁 ,为了保证所有蚂蚁在消息传送的时候都能接收到消息,需要在他们之间建立通信关系。就是要求小蚂蚁都可以通过多只或者直接联系到其他人。 已知几条小蚂蚁之间有通信关系,请问还需要再新建至少多少条关系? 

         根据题意,判断已有联通块的数目减1就是答案,可以用并查集维护连通块。

#include <bits/stdc++.h>
using namespace std;
const int maxn = 1010;
int fa[maxn];
int find(int x) { return fa[x] == x ? x : fa[x] = find(fa[x]); }
void unite(int x, int y)
{
    int fx = find(x), fy = find(y);
    if (fx == fy)
        return;
    fa[fx] = fy;
}
int main()
{
    int n, m;
    scanf("%d%d", &n, &m);
    for (int i = 1; i <= n; ++i)
        fa[i] = i;
    for (int i = 0, x, y; i < m; ++i)
    {
        scanf("%d%d", &x, &y);
        unite(x, y);
    }
    int ans = 0;
    for (int i = 1; i <= n; ++i)
        if (find(i) == i)
            ++ans;
    printf("%d\n", ans - 1);
    return 0;
}

4. 题目名称:小股炒股  

已知n天后的股票行情,现在已有的本金是m, 规定只能入手一次股票和抛售一次股票。 最大收益(含本金)是? 

        根据题意,可以从后往前枚举买哪只股票,然后计算最大收益。

#include <bits/stdc++.h>
using namespace std;
const int maxn = 1010;
int p[maxn];
int main()
{
    int n, m;
    scanf("%d%d", &n, &m);
    for (int i = 0; i < n; ++i)
        scanf("%d", p + i);
    int mx = 0, ans = 0;
    for (int i = n - 1; i >= 0; --i)
    {
        mx = max(mx, p[i]);
        ans = max(ans, m + (mx - p[i]) * (m / p[i]));
    }
    printf("%d\n", ans);
    return 0;
}

 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值