2021-4-17学习总结5
上周六晚上在codeforces上打了一场div.2的比赛,第一题的感觉与div.3的比赛相比饶了很多弯,但是最后发现题目的本身还是挺简单的。但是第二题我就没有理解题目的含义没有做出来。
A题
题意:有三种类型的评论员,他们依次到来,一种反对者,一种支持者,还一种随波逐流的人,即根据当前情况,如果反对数 > 支持数,就投反对,反之投支持的人,现在你有两个投票系统,你可以选择给当前来到的客人展示其中一种,问你最多可以获得多少票支持。
//错误代码:
#include <cstdio>
#include<iostream>
using namespace std;
int main()
{
int t;
cin >> t;
while (t--)
{
int n, a, f1[2] = { 0 }, f2[2] = { 0 };
cin >> n;
for (int i = 0; i < n; i++) //写了一大长串没有一点用,即考虑这又考虑那,完全没有用
{ //只要保证3的人都投赞成票即可为最大赞成票数
cin >> a;
if (a == 1)
{
if (f1[0] < f1[1] && f2[0] >= f2[1]) f1[0]++;
if (f1[0] >= f1[1] && f2[0] < f2[1]) f2[0]++;
if (f1[0] >= f1[1] && f2[0] >= f2[1])
if (f1[0] - f1[1] > f2[0] - f2[1]) f2[0]++;
else f1[0]++;
if (f1[0] < f1[1] && f2[0] < f2[1])
if (f1[1] - f1[0] > f2[1] - f2[0]) f2[0]++;
else f1[0]++;
}
if (a == 2)
{
if (f1[0] < f1[1] && f2[0] >= f2[1]) f2[1]++;
if (f1[0] >= f1[1] && f2[0] < f2[1]) f1[1]++;
if (f1[0] >= f1[1] && f2[0] >= f2[1])
if (f1[0] - f1[1] > f2[0] - f2[1]) f1[1]++;
else f2[1]++;
if (f1[0] < f1[1] && f2[0] < f2[1])
if (f1[1] - f1[0] > f2[1] - f2[0]) f1[1]++;
else f2[1]++;
}
if (a == 3)
{
if (f1[0] < f1[1] && f2[0] >= f2[1]) f2[0]++;
if (f1[0] >= f1[1] && f2[0] < f2[1]) f1[0]++;
if (f1[0] >= f1[1] && f2[0] >= f2[1])
if (f1[0] - f1[1] > f2[0] - f2[1]) f2[0]++;
else f1[0]++;
if (f1[0] < f1[1] && f2[0] < f2[1])
if (f1[1] - f1[0] > f2[1] - f2[0]) f1[1]++;
else f1[1]++;
}
}
cout << f1[0] + f2[0] << endl;
}
return 0;
}
最后我发现写了一大长串没有一点用,即考虑这又考虑那,完全没有用。真正的题意是让第三种人全投赞成票即是最大获得的投票数。(因为第二种人全是投反对票)让第一种人和第三种人进入第一个服务器,第二种人进入第二个服务器即可。即统计第一种人和第三种人的个数即可。
正确代码:
#include<iostream>
using namespace std;
int main()
{
int t;
cin >> t;
while (t--)
{
int n, a, f1 = 0 , f2 = 0;
cin >> n;
for (int i = 0; i < n; i++)
{
cin >> a;
if (a == 1||a == 3) f1++;
}
cout << f1 << endl;
}
return 0;
}
这道题让我感受到比赛最重要的是思路,没有正确的思路什么都不是。比赛要求选手的临时应变能力和反应速度。而且在两个小时中完成7道题目最显著的我来说两个小时完成div.3的三道题目都做不到。需要继续努力。
在做题中我也学到了很多如在B体中用到了unordered_map比map的查找速度快,而且是无序的。
int a[]; cin>>a+1;是从a[1]开始读入而且可以读到换行符或者最大下标,一般用于没有空格,一连串的输入,即两个字母之间没有任何字符。
错误代码:
#include<cstdio>
#include<iostream>
#include <unordered_map>
#include <cmath>
#include <cstring>
#include <string>
#include<algorithm>
#include<map>
using namespace std;
const int maxn = 10005; //没有maxn一样过
int dp[maxn][maxn]; //开在main外,在main函数里无法运行,会报错
char a[maxn], b[maxn], c[maxn]; //多了c[maxn]导致程序运行错误(但在vs2019中可以运行)
unordered_map<char, int> m;
int main()
{
int n;
while (cin >> n) //(cin >> n,n)//遇到0停止但是不知道为什么导致AC不了,时间超时
{
for (int i = 0; i < n; i++)
cin >> c[i];
for (int i = 0; i < n; i++)
cin >> m[a[i]];
cin >> a + 1;
int n1 = strlen(a + 1);
cin >> b + 1;
int n2 = strlen(b + 1);
for (int i = 1; i <= n1; i++)
for (int j = 1; j <= n2; j++)
{
dp[i][j] = max(dp[i - 1][j], dp[i][j - 1]);//第i颗子弹不可以杀死第j个恐怖分子时,要不是第i颗子弹杀死第j-1个恐怖分子,要不是第i颗子弹杀死第j-1个恐怖分子,两种情况。dp方程还算简单
if (a[i] == b[j])
dp[i][j] = max(dp[i][j], dp[i - 1][j - 1] + m[a[i]]); //刚好第i颗子弹可以杀死第j个恐怖分子时
}
cout << dp[n1][n2] << endl;
}
return 0;
}