好吧,可能是我的文字功底太弱了,首先滴就是这个B题
题目链接
我一开始还以为这个能排序,就是算排完序之后的最大差,但是仔细一看题目,好像不要求使用排序,于是就尝试暴力做法。我发现的暴力做法是枚举k,直到k == n / 2为止,当时是因为没有开long long导致WA了,后面发现时间不是怎么多就没有在意这道题,现在,差不多弄懂了。
然后就是这个C题
题目链接
碰到这种字串类型的题目我一般是想用暴搜的,但是这题数据范围给的太大,暴力肯定过不了,但是当时一时半会也想不出来别的O(n)的方法。这题说的满足条件的字串有一个条件,前后两个数是奇偶交替,这个条件好处理,我们需要想出一个O(n)的方法,或者是O(nlogn)的方法,首先O(n)的方法一般是遍历数组,然后在遍历的时候进行相关操作。这题我们需要用到一点贪心的思想,首先想要让选中的数组串尽可能的大就需要第一个数就是正数,然后在遍历的时候数组串相加不能为复数,如果是负数,就重新开始算字串,因为假如有一个正数,我选这个正数为字串,是一定比0大的结果。最后我们得到一个算法:让i遍历整个数组,然后用一个变量来计数,如果sum < 0,那么重新计数,这就能包含两种情况,第一是算进去的第一个数就是负数,第二个是数组串的和是负数,其实都是一样的,第一种就是第二种的特殊情况,然后遇到前后奇偶不一的情况也是sum = 0 重新计数,最后让ans在sum里面取最大值就行。
最后是D题
题目链接
这题要稍微用到点中学数学知识,题目的要求是要我们找到i < j并且(2a)(2^b) == (2b)(2^a),这个式子我们可以简化,两边同时去对数,会得到a * 2^b == b * 2^a然后再去一遍得到 aln2 - lna == bln2 - lnb,就是相当于函数x*ln2 - lnx的图像上有没有X0,X1为整数且值相等的点
我去画了一下这个函数的图像:
发现除了1和2,其他所有的数满足条件的只有这个数和这个数自己,那么就好办了,我们只需要用一个map来存下出现的数的次数,然后算他自己和自己的所有不重复的组合即可,这里我们注意,我们可以把1和2当成同一个数因为条件上,1和2是相同的性质。这里我们假如我们有个数n出现次数k那么他自己所有的排列为((k - 1)*k)) / 2注意不能直接除2,因为k - 1或k不确定奇偶性,可能有向下取整的误差。最后,注意开long long
D题码:
#include <iostream>
#include <algorithm>
#include <vector>
#include <cmath>
#include <map>
#define int long long //爆了int就用这个,方便快捷
using namespace std;
const int N = 200010;
void solve()
{
map<int, int> a;
int n, x;
cin >> n;
vector<int> b(n + 1, 0);
for (int i = 1; i <= n; i++)
{
cin >> x;
b[i] = x;
a[x]++;
}
int ans = 0;
for (int i = 1; i <= n; i++)
{
if (a[b[i]] == 0)
continue;
if (b[i] == 1 || b[i] == 2)
{
ans += ((a[1] + a[2] - 1) * (a[1] + a[2])) / 2;
a[1] = 0, a[2] = 0;
}
else
{
ans += ((a[b[i]] - 1) * a[b[i]]) / 2;
a[b[i]] = 0;
}
}
cout << ans << endl;
}
signed main() //注意用了define int就需要把原先的int main换成signed main
{
int tNum;
cin >> tNum;
for (int i = 0; i < tNum; i++)
{
solve();
}
return 0;
}
标签:题目,这题,--,909,Codeforces,long,int,字串,include
From: https://www.cnblogs.com/chhh31/p/18338950