题解 P9472 [yLOI2022] 枕万梦

算法概述:

本题是一道非常典型的结构体排序的题。

题意讲解:

本题的大概意思就是给定 \(n\) 个数组的第一项,推算出数组的各项,对这 \(n\) 个数组都不同的一项进行对数组的排序。

暴力做法(30分)

这题大家最容易想到的方法就是将所有的数据算出来然后再去找 \(p\),但是如果我们看一眼数据范围:

  • \(1 \le m \le 10^9\)
  • \(1 \leq |a_{i,0}| \leq 10^9\)

咱先不说会不会 TLE,就这 \(a_{i,n}\) 乘出来都得炸long long,所以这种做法直接 Pass 掉。
(作者当时就用了这种做法,挂了70分)

满分做法

我们仔细看一看题目:第 \(i\) 个数列 \(a_i\) 满足递推式 \(a_{i,j} = a_{i,j - 1} \times i\)

发现没有,推断 \(a_{i,j}\) 的递推式结尾乘上了一个 \(i\),这就能推断出以下内容。

\(p\) 只有一下两种情况:

  • \(a_{i,0}\) 不相等,\(p = 0\)
  • \(a_{i,0}\) 相等,但因乘上一个 \(i\) 而导致 \(a_{i,1}\) 不相等,\(p = 1\)

例:\(a_{1,0} = 1, a_{2,0} = 1\),根据递推公式推出 \(a_{1,1} = 1, a_{2,1} = 2\)\(p = 1\)

由此我们可以看出,\(p\) 只有 0 和 1 两种情况,所以我们只算前两项就可以啦!

为了应对极端情况,记得开long long

贴代码:

#include <bits/stdc++.h>
#define ll long long
using namespace std;
ll n, m;
struct Node
{
    ll a1, a2;
    int id;
} a[100005];
bool cmp(Node x, Node y)
{
    if (x.a1 != y.a1)
        return x.a1 < y.a1;
    else
        return x.a2 < y.a2;
}
int main()
{
    cin >> n >> m;
    for (ll i = 1; i <= n; i++)
    {
        cin >> a[i].a1;
        a[i].id = i;
        a[i].a2 = a[i].a1 * i;
    }
    sort(a + 1, a + n + 1, cmp);

    for (ll i = 1; i <= n; i++)
        cout << a[i].id << " ";
    cout << endl;
    return 0;
}

附件:

30分暴力代码:

// 暴力用的是vector和结构体,代码略繁琐,建议不要使用。
#include <bits/stdc++.h>
using namespace std;
vector<int> a[100005];
int n, m;
struct Compare
{
    int value;
    int number;
} c[100005];
bool cmp(Compare x, Compare y)
{
    return x.value < y.value;
}
int main()
{
    cin >> n >> m;
    for (int i = 1; i <= n; i++)
    {
        int x;
        cin >> x;
        a[i].push_back(x);
    }
    for (int i = 1; i <= n; i++)
    {
        for (int j = 1; j < m + 1; j++)
            a[i].push_back(a[i][j - 1] * i);
    }

    int p;
    for (p = 0; p < m + 1; p++)
    {
        bool flag = true;
        for (int i = 1; i < n; i++)
        {
            if (!(a[i][p] != a[i + 1][p]))
            {
                flag = false;
                break;
            }
        }
        if (flag)
        {
            for (int i = 1; i <= n; i++)
            {
                c[i].value = a[i][p];
                c[i].number = i;
            }
            break;
        }
    }
    sort(c + 1, c + n + 1, cmp);

    for (int i = 1; i <= n; i++)
        cout << c[i].number << " ";
    cout << endl;
    return 0;
}

点我返回题目

posted @ 2024-08-20 17:37  George0915  阅读(25)  评论(0)    收藏  举报