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;
}