一开始的思路就是暴力,先求出最后一个值的位置op,然后遍历数组,找到第op个没有被占领的点,将最后一个值存到这个点,然而TLE了。

TLE代码

#include <iostream>
#include <cmath>
using namespace std;
int a[100001], ans[100001], book[100001];
//book[i]记录点i是否被占领
int main()
{
    int n;
    scanf("%d", &n);
    int t = n;
    for (int i = 1; i <= n; i++)
        scanf("%d", &a[i]);
    for (int i = 1; i <= n; i++)
    {
        int op = sqrt(t);
        t--;
        int cnt = 0;
        for (int j = 1; j <= n; j++)
        {
            if (book[j] == 0)
            {
                cnt++;
                if (cnt == op)
                {
                    book[j] = 1;
                    ans[j] = a[i];
                }
            }
        }
    }
    for (int i = 1; i <= n; i++)
        printf("%d%c", ans[i], i == n ? '\n ' : ' ');
}

然后在纸上模拟发现了一点规律,然后就打个表,好了,AC了。下面的打表的代码,当n=30时

从后往前遍历,每k个元素(k=3,5,7,9),将前k-1个元素放入答案数组尾部,1个元素放入答案数组头部,直到遍历完a数组就好了。

打表代码

#include <iostream>
#include <cmath>
using namespace std;
int a[100001], ans[100001], book[100001];
int main()
{
    int n, x = 1;
    scanf("%d", &n);
    int t = n;
    for (int i = 1; i <= n; i++)
        a[i] = i;//scanf("%d", &a[i]);
    for (int i = 1; i <= n; i++)
    {
        int op = sqrt(t);
        t--;
        int cnt = 0;
        for (int j = 1; j <= n; j++)
        {
            if (book[j] == 0)
            {
                cnt++;
                if (cnt == op)
                {
                    book[j] = 1;
                    ans[x++] = a[j];
                }
            }
        }
    }
    for (int i = 1; i <= n; i++)
        printf("%d%c", ans[i], i == n ? '\n' : ' ');
}

AC代码

#include <iostream>
#include <cmath>
using namespace std;
int a[100001], ans[100001];
int main()
{
    int n, x = 3, f = 3;
    scanf("%d", &n);
    int head = 1, tail = n;
    for (int i = 1; i <= n; i++)
        scanf("%d", &a[i]);
    for (int i = n; i >= 1; i--)
    {
        if (n - i + 1 < x)
            ans[tail--] = a[i];
        else
        {
            ans[head++] = a[i];
            f += 2;
            x += f;
        }
        if (head > tail)
            break;
    }
    for (int i = 1; i <= n; i++)
        printf("%d%c", ans[i], i == n ? '\n' : ' ');
}
/************************************************************** Problem: 1015 User: Language: C++ Result: 正确 Time:39 ms Memory:2804 kb ****************************************************************/