Codeforces Round #631 (Div. 2)未完待续......

这次是Dreamoon大佬出的题,毫无意外掉分了QAQ,第一次被hack,收获很大 /偷看 ,自己还要努力!!

A. Dreamoon and Ranking Collection

题目大意:给你n个数和一个数k,让插入k个数,使得1-v连续,输入最大数v。

题解:输入的同时使用vis做标记,然后从1遍历一遍,当vis没有被标记的时候,就使用一次插空的机会。

坑点 :你要用当k+1次时再break,然后ans-1。如果你从k就跳出,你可能从后面又连续了。(我就是这样被hack了)

AC代码:

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const double PI = acos(-1.0);
bool vis[300];
int main()
{
    ios::sync_with_stdio(false);
    int t, n, x, y, temp = 0;
    int a[105];
    cin >> t;
    while (t--)
    {
        cin >> n >> x;
        memset(vis, 0, sizeof(vis));
        for (int i = 1; i <= n; i++)
        {
            cin >> y;
            vis[y] = 1;
        }
        int ans = 0, cnt = 0;
        for (int i = 1;; i++)
        {
            if (vis[i] == 0)
                ++cnt;
            ans = i;
            if (cnt == x + 1)
                break;
        }
        cout << ans-1 << endl;
    }
    return 0;
}

B. Dreamoon Likes Permutations

题目大意:给你n个数从a1到an。现在让你找到长度为len和n-len长的序列,使得序列中包含1到len和1到n-len的所有数。你不能打乱原来的序列顺序。若能找到输出这两个序列的长度和总共种类数。

题解: 我用的前n项和的求和公式优化和bool数组桶排的思想标记1到len的所有数。

AC代码:

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const double PI = acos(-1.0);
int t, n;
bool vis[200005];
ll a[200005];
ll sum[200005];
vector<int> ans;
#define rep(i, a, b) for (int i = a; i <= b; i++)
int main()
{
    ios::sync_with_stdio(false);
    cin >> t;
    while (t--)
    {
        sum[0] = 0;
        cin >> n;
        rep(i, 1, n)
        {
            cin >> a[i];
            sum[i] = sum[i - 1] + a[i]; //记录前缀和
        }
        ans.clear();
        bool flag1 = 0, flag2 = 0;
        for (ll i = 1; i < n; i++)
        {
            ll temp = (1 + i) * i / 2;
            ll temp2 = (1 + n - i) * (n - i) / 2;
            if (sum[i] == temp && sum[n] - sum[i] == temp2) //利用等差求和和前n项和公式
            {
                memset(vis, 0, sizeof(vis));
                flag1 = flag2 = 0;
                for (int j = 1; j <= i; j++) //在第一段1-i的长度进行标记a[i]的所有数字
                {
                    if (vis[a[j]] == 0)
                        vis[a[j]] = 1;
                    else
                    {
                        flag1 = 1;
                        break;
                    }
                }
                if (flag1 == 0)
                {
                    for (int j = 1; j <= i; j++) //查找1-i长度的序列是否又1-i中所有的数
                    {
                        if (vis[j] == 0)
                        {
                            flag1 = 1;
                            break;
                        }
                    }
                }

                if (flag1 == 0)
                {
                    memset(vis, 0, sizeof(vis));
                    for (int j = i + 1; j <= n; j++) //同理第二段也是
                    {
                        if (vis[a[j]] == 0)
                            vis[a[j]] = 1;
                        else
                        {
                            flag2 = 1;
                            break;
                        }
                    }
                    if (flag2 == 0)
                    {
                        for (int j = 1; j <= n - i; j++)
                        {
                            if (vis[j] == 0)
                            {
                                flag2 = 1;
                                break;
                            }
                        }
                        if (flag2 == 0)
                            ans.push_back(i);
                    }
                }
            }
        }
        cout << ans.size() << endl; //输出答案
        for (int i = 0; i < ans.size(); i++)
            cout << ans[i] << " " << n - ans[i] << endl;
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/acm_durante/article/details/105334014