目录
感染源在哪里
通过最近的一次核酸检测,疫情防控小组检测到了若干个阳性人员,通过调取行程码数据,防控小组获取到了这些病例曾经去过的地点。现在希望对这些地点做源头可能性分析,来找出哪些地点更有可能是本次疫情的源头。
对于一个病例,如果其曾到过a,b,c三个地点,那么这三个地点都会在其源头可能得分上增加1/3,如果某个病例曾经去过a,c两个地点,那么这两个地点作为源头的得分都会增加1/2,如果只去过一个地点的病例,那么该地点作为源头的概率很高,我们给这个地点的得分增加1。
简而言之,如果一个病例去过n个地点,那么这n个地点都会得到1/n的得分。现在给你所有病例去过的地点的情况,你能否分析出每个地点作为源头的可能性大小顺序?
输入格式:
第一行一个整数n(1≤n≤1000),表示记录的条数
其后n行,每行两个不为空的字符串a,b(1≤∣a∣,∣b∣≤10),仅包含小写字母。其中a代表病例的名字,b代表地点。注意:当出现有人多次去同一地点时,只计算一次
输出格式:
输出若干行,每行代表一个地点名,代表所有地点作为源头的得分从高到低排序的结果。如果有多个地点得分相同,地点名字典序小的优先。
输入样例:
6 xiaoa adian xiaob adian xiaob bdian xiaoc adian xiaoc bdian xiaoc cdian
输出样例:
adian bdian cdian
代码长度限制
16 KB
时间限制
1000 ms
内存限制
64 MB
思路:
模拟:去重 + 排序
可以使用vector去重的方法
去除重复元素 vector<string> vec vec.erase(unique(vec.begin(),vec.end()),vec.end());
赛时忘了去除咋写了,就用map解决了
AC代码如下:
#include <bits/stdc++.h>
#define buff \
ios::sync_with_stdio(false); \
cin.tie(0); \
cout.tie(0)
using namespace std;
const int N = 1009;
int n;
map<string, int> m;
vector<string> s[N];
int cnt = 0;
struct mm
{
map<string, int> check;
} cf[N];
struct nn
{
string name;
double q = 0;
} tt[N];
map<string, int> t;
int cnt2 = 0;
bool cmp(nn x, nn y)
{
if (x.q != y.q)
return x.q > y.q;
else
return x.name < y.name;
}
int main()
{
buff;
cin >> n;
for (int i = 1; i <= n; i++)
{
string a, b;
cin >> a >> b;
if (!m[a])
{
m[a] = ++cnt;
}
if (!cf[m[a]].check[b])
{
cf[m[a]].check[b] = 1;
s[m[a]].push_back(b);
}
}
for (int i = 1; i <= cnt; i++)
{
int num = s[i].size();
for (int j = 0; j < num; j++)
{
string tmp = s[i][j];
if (!t[tmp])
{
t[tmp] = ++cnt2;
tt[cnt2].name = tmp;
}
tt[t[tmp]].q += 1.0 / num;
}
}
sort(tt + 1, tt + 1 + cnt2, cmp);
for (int i = 1; i <= cnt2; i++)
cout << tt[i].name << "\n";
}
病毒序列
时至至今,疫情还没结束,战斗并未停止!现如今,疫情肆虐全球,疫情的传播加速了病毒的变异,α病毒,β病毒,δ病毒,相继出现...
而小A对病毒的变异来了兴趣,带着高中学过的生物知识,小A了解到病毒可以表示为由A,U,C,G四种碱基组成的基因序列,而病毒的变异便来自于不同基因序列结合。在此,我们将两个不同的基因序列的结合定义为:两个基因序列上下排布,通过一定的错位,使得两个基因序列的部分碱基可以对应起来,若分属两个基因序列的A与U对应则形成3个氢键,若分属两个序列的C与G对应会形成2个氢键,如图所示:
顽固的病毒为了保证自己结构的稳定性,在变异过程中总会选择形成氢键个数最大的方式进行结合。现在给定两个基因序列,他们结合后的氢键个数是多少?
PS:题目描述的“结合”仅仅为本题目描述所定义,不一定符合真实的生物学性质。
输入格式:
两行,每行一个字符串,分别是两个待结合的基因序列。(保证字符串只有A,U,C,G组成,且字符串的长度小于等于5000).
输出格式:
一行一个整数,表示结合后的最大氢键个数。
输入样例:
AGC UUCG
输出样例:
7
样例解释
共有6种可能的结合方式
AGC UUCG AGC UUCG AGC UUCG AGC UUCG AGC UUCG AGC UUCG
其中形成氢键的个数分别为:3,0,0,7,0,0
则病毒序列会选择氢键个数为7的方式进行结合代码长度限制
16 KB
时间限制
1000 ms
内存限制
128 MB
思路:
枚举:分别枚举两串的相对位置关系
推荐方法:
约定:两串分别为 a串, b串。
【1】a串固定,b串移动
【2】b串固定,a串移动
枚举所有位置情况所对应的氢键个数,取最大值并输出。
AC代码如下:
#include <bits/stdc++.h>
#define buff \
ios::sync_with_stdio(false); \
cin.tie(0); \
cout.tie(0)
using namespace std;
const int N = 5009;
char s1[N];
char s2[N];
int n1, n2;
int ans = 0;
int func(char x, char y)
{
if ((x == 'A' && y == 'U') || (x == 'U' && y == 'A'))
return 3;
else if ((x == 'C' && y == 'G') || (x == 'G' && y == 'C'))
return 2;
else
return 0;
}
void check1(int idx)
{
int sum = 0;
for (int i = idx, j = 0; i < n2 && j < n1; i++, j++)
{
sum += func(s2[i], s1[j]);
}
if (sum > ans)
ans = sum;
}
void check2(int idx)
{
int sum = 0;
for (int i = idx, j = 0; i < n1 && j < n2; i++, j++)
{
sum += func(s1[i], s2[j]);
}
if (sum > ans)
ans = sum;
}
int main()
{
buff;
cin >> s1;
cin >> s2;
n1 = strlen(s1);
n2 = strlen(s2);
// s1移动
for (int i = 0; i < n2; i++)
{
check1(i);
}
// s2移动
for (int i = 0; i < n1;i++)
{
check2(i);
}
cout << ans << "\n";
}
奇奇怪怪的形状
小凡有一张边长为2的正方形白纸,上面画了2×2个边长为1的格子,每个格子上可以放置棱长为1的立方体。小凡手中有若干个棱长为1的立方体,他随机地在每个格子上放置一些立方体,求由这些立方体组成的几何体的表面积。
输入格式:
输入两行,每行两个不超过100的正整数,代表从俯视的角度看,白纸所画每个格子上立方体的数量。
输出格式:
输出一行,包含一个整数,表示几何体的表面积。
输入样例:
上图对应的输入数据如下:
2 1 1 1
输出样例:
20
代码长度限制
16 KB
时间限制
1000 ms
内存限制
128 MB
思路:
关于 由立方体组成的几何体的表面积 :
我们可以分为6个视角来分别算 每个视角对应的面积,最后加一起就是表面积。
也可以是两(四)个视图(俯视or仰视,左or右视图)的面积 和* 2
S(表面积) =[ S(俯or仰) + S(左or右)] * 2
AC代码如下:
#include <bits/stdc++.h>
#define buff \
ios::sync_with_stdio(false); \
cin.tie(0); \
cout.tie(0)
using namespace std;
int a, b, x, y;
int s[4];
int main()
{
buff;
cin >> a >> b >> x >> y;
int ans = 0;
//四个视角
//正 + 后
int one = max(a, x);
int two = max(b, y);
ans += (one + two) * 2;
//左 + 右
one = max(a, b);
two = max(x, y);
ans += (one + two) * 2;
//上+下
ans += 4 * 2;
cout << ans << endl;
}