CF赛后总结2:2021-07-14晚 ECR111 div2 rating+335

  • 题库链接:link<-----div2ECR111题库
  • A题:link 思维题
  • 1、题意:一个数-1要存在于数组中,或者-2存在于数组中或者本身为1给出一个数问最少可以分成多少个元素使得数组中每个元素都满足以上条件
  • 2、转化:直接每次+2取最大条件就好,遍历到sum大于等于n就break
#include<iostream>
#include<algorithm>
using namespace std;
int main()
{
    int t; cin >> t;
    while (t--)
    {
        int n; cin >> n;
        if (n == 1)
        {
            cout << 1 << endl;
            continue;
        }
        //奇数从1开始偶数从2开始每次+2就是答案
        int cnt = 1, sum = 1;
        for (int i = 3;; i += 2)
        {
            cnt++;
            sum += i;
            if (sum >= n)break;
        }
        cout << cnt << endl;
    }
    return 0;
}
  • B:link 思维题
  • 1、题意:输出数组长度乘以a与操作次数乘以b的最大值,a*len是个定值所以关键在于删除连续串的操作次数
  • 2、转化:要是b大于0就一个一个删除这样得分最大,要是b小于0就一段一段删除这样b的影响最小也是得分最大,求最小操作次数是用定1清0或者定0清1,比如10001010100,先删除所有连续的0,最后的操作次数就是操作数加1
#include<iostream>
#include<algorithm>
using namespace std;
const int N = 110;
char map[N];
int main()
{
    int t; cin >> t;
    while (t--)
    {
        int n, a, b;
        cin >> n >> a >> b;
        for (int i = 0; i < n; i++)
            cin >> map[i];
        //a不影响分数一定是a*n
        //b影响分数,求出多少次清空数组的ans
        if (b >= 0)
        {
            cout << (a + b) * n << endl;
        }
        else
        {
            int ans = 1;
            //100100100011101
            //定1清0法
            int l = 0, r = 1;
            while (l < n && r < n)
            {
                while (map[r] != map[l] && r < n)r++;
                if (map[r - 1] != map[l])ans++;
                r++;
            }
            cout << a * n + b * ans << endl;
        }
    }
    return 0;
}
  • C:link 思维题
  • 1、题意:找出这样的连续子串
  • (subarrays(连续子串))
  • (subsequence(可以不连续的子串))
  • 使得该连续子串中任意三个元素都不会形成题目描述的坏的三元组,这样的子串叫做好子串,统计这样的子串的个数
  • 2、转化:因为下标是有序的,所以要保证是好的子串该三元组必须不满足单调即必须是非单调上升或者单调递减的,因为
  • (x,1)(y,2)(z,3)
  • 要是x < y < z
  • a = y - x + 1
  • b = z - y + 1
  • c = z - x + 2
  • 按照这种c = a + b一定是坏的即只要满足条件:
  • min(x1,x3) < x2 < max(x1,x3)和
  • min(y1,y3) < y2 < max(y1,y3)就是坏的三元组,所以数据组一定不能有序,但又发现只要数据组元素超过四个就一定会出现有序的情况,所以只考虑3、4,开始时ans是子串中元素个数是1和2的情况数就是n + n - 1
#include<iostream>
using namespace std;
const int N = 2e5 + 10;
int a[N];

int main()
{
	int t; cin >> t;
	while (t--)
	{
		int n; cin >> n;
		for (int i = 1; i <= n; ++i) cin >> a[i];
		long long ans = n + n - 1;// 1个两个的串一定是好串
		for (int i = 2; i <= n - 1; i++)
		{
			if (!(a[i - 1] <= a[i] && a[i] <= a[i + 1] || a[i - 1] >= a[i] && a[i] >= a[i + 1]))ans++;
		}
		for (int i = 2; i <= n - 2; i++)
		{
			bool flag1 = false;
			bool flag2 = false;
			bool flag3 = false;
			if (!(a[i - 1] <= a[i] && a[i] <= a[i + 1] || a[i - 1] >= a[i] && a[i] >= a[i + 1]))flag1 = true;
			if (!(a[i - 1] <= a[i] && a[i] <= a[i + 2] || a[i - 1] >= a[i] && a[i] >= a[i + 2]))flag2 = true;
			if (!(a[i - 1] <= a[i + 1] && a[i + 1] <= a[i + 2] || a[i - 1] >= a[i + 1] && a[i + 1] >= a[i + 2]))flag3 = true;
			if (flag1 && flag2 && flag3 && !(a[i] <= a[i + 1] && a[i + 1] <= a[i + 2] || a[i] >= a[i + 1] && a[i + 1] >= a[i + 2]))ans++;
		}
		cout << ans << endl;
	}
}
  • 2021-11-03写于赣州

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值