Codeforces Round #649 (Div. 2)(烂!!!!)A-B

A

Ehab loves number theory, but for some reason he hates the number x. Given an array a, find the length of its longest subarray such that the sum of its elements isn’t divisible by x, or determine that such subarray doesn’t exist.

An array a is a subarray of an array b if a can be obtained from b by deletion of several (possibly, zero or all) elements from the beginning and several (possibly, zero or all) elements from the end.

Input
The first line contains an integer t (1≤t≤5) — the number of test cases you need to solve. The description of the test cases follows.

The first line of each test case contains 2 integers n and x (1≤n≤105, 1≤x≤104) — the number of elements in the array a and the number that Ehab hates.

The second line contains n space-separated integers a1, a2, …, an (0≤ai≤104) — the elements of the array a.

Output
For each testcase, print the length of the longest subarray whose sum isn’t divisible by x. If there’s no such subarray, print −1.

Example
input
3
3 3
1 2 3
3 4
1 2 3
2 2
0 6
output
2
3
-1
Note
In the first test case, the subarray [2,3] has sum of elements 5, which isn’t divisible by 3.

In the second test case, the sum of elements of the whole array is 6, which isn’t divisible by 4.

In the third test case, all subarrays have an even sum, so the answer is −1.
题意:就是一排数组问你经过操作后 最长的序列和%i!=0;
操作就是可以删除左边的或者右边的
自己读题除了问题

#include<iostream>
#include<cstring>
#include<cstdio>
#include<cmath>
#include<string>
#include<iomanip>
#include<vector>
#include<fstream>
using namespace std;
typedef long long ll;
ll a[1000000], s[1000000];
int main()
{
    int t; cin >> t;
    while (t--)
    {
        int n; cin >> n; int x; cin >> x;
        for (int i = 1; i <= n; i++)
        {
            cin >> a[i];
            s[i] = s[i - 1] + a[i];
        }
        if (s[n] % x != 0)
            cout << n << endl;
        else
        {
            int ans =-1;
            for (int i = 1; i <= n; i++)
            {
                if ((s[n] - s[i]) % x != 0)
                {
                    ans = ans > (n - i) ? ans : (n - i);
                    break;
                }
            }
            for (int i = n; i >= 1; i--)
            {
                if (s[i] % x != 0)
                {
                    ans = ans > i ? ans : i;
                    break;
                }
            }
            cout << ans << endl;
        }
    }
}

B

原题:

Given a permutation pp of length nn , find its subsequence s1 , s2 , …… , sk of length at least 2 such that:

|s1−s2|+|s2−s3|+…+|sk−1 − sk|is as big as possible over all subsequences of pp with length at least 2 .
Among all such subsequences, choose the one whose length, k , is as small as possible.
If multiple subsequences satisfy these conditions, you are allowed to find any of them.

A sequence aa is a subsequence of an array b if a can be obtained from b by deleting some (possibly, zero or all) elements.

A permutation of length n is an array of length n in which every element from 1 to n occurs exactly once.

输入:

The first line contains an integer t (1≤t≤2⋅10^4) — the number of test cases. The description of the test cases follows.

The first line of each test case contains an integer n (2≤n≤10^5) — the length of the permutation p.

The second line of each test case contains n integers p1, p2, ……, pn(1≤pi≤n1, pipi are distinct) — the elements of the permutation p.

The sum of nn across the test cases doesn’t exceed 10^5

输出:

For each test case, the first line should contain the length of the found subsequence, k. The second line should contain s1, s2, ……, sk — its elements.

If multiple subsequences satisfy these conditions, you are allowed to find any of them.

样例:

Input:

2
3
3 2 1
4
1 3 4 2

Output:

2
3 1
3
1 4 2
题意:找出一个序列 使得 序列尽量短 而 序列数字前后的差的绝对值的和尽量大
思路: (1, 2, 3, 8, 7, 11, 13) 的 邻间项差的和是 1 + 1 + 5 + 1 + 4 + 4 = 2 + 5 + 1 + 8;

我们不难理解,不论如何删去项,我们所得的 邻间项差的和 总是小于等于n个数间的 邻间项差的和,所以只需判断如何去项能去掉最多的项,并且保持和不变;我们可以看粗 1 2 3 间的邻间项差的和是 2 = 3 -1;中间的2对结果并没有影响,同理也能看出 7 11 13也满足,但是 3 8 7间却不满足;所以说,只有中间的数夹在两边的数直接,这个数才对结果没有影响,可以删去,所以运用循环判断,计数,并标记是否能输出。
即把递增递减序列中间的数字去掉就行

#include<iostream>
#include<cstring>
#include<cstdio>
#include<cmath>
#include<string>
#include<iomanip>
#include<vector>
#include<algorithm>
using namespace std;
typedef long long ll;
int a[1000000];
int s[1000000];
int main()
{
    int t; cin >> t;
    while (t--)
    {
        int n; cin >> n;
        for (int i = 1; i <=n; i++)
        {
            cin >> a[i];
            s[i] = 0;
        }
        int lon = 0;
        for (int i =2; i<n; i++)
        {
            if ((a[i] >= a[i - 1] && a[i] <= a[i + 1]) || (a[i] <= a[i - 1] && a[i] >= a[i + 1]))
            {
                s[i] = 1;
                lon++;
            }
        }
        cout << n - lon << endl;
        for (int i=1; i <= n; i++)
        {
            if (s[i]==0)
                cout << a[i] << " ";
        }
        cout << endl;
    }
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值