求证明正确性or hack
查看原帖
求证明正确性or hack
339442
SXqwq楼主2023/8/21 11:07

赛时做法,AC,思路比较清奇。

具体思路就是让每个数尽可能产生贡献,先输出p的整数倍,然后再尽可能让每个数产生贡献。枚举每个非p的整数倍的数,然后尽可能输出能和它相加成p的整数倍的数,当然我们希望尽可能延续,所以需要记录一个pos

我不会证明,看了一下讨论区都没有这么做的,代码:

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
using namespace std;
const int N = 100010;
int T;
void print(int n)
{
    for(int i=1;i<=n;i++) cout<<i<<" ";
    cout<<endl;
}
int vis[N];
int main()
{   
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    cin>>T;
    while(T--)
    {
        memset(vis,0,sizeof(vis));
        int n,p;
        cin>>n>>p;
        int maxn = -1;
        if(p == 1 || n+n-1 < p){ print(n); continue;}
        for(int i=1;i;i++) 
        {
            if(p*i > n) 
            {
                maxn = p*(i-1);
                break;
            }
            if(p*i <= n){ cout<<p*i<<" ";vis[p*i] = 1;}
        }
        for(int i=1;i<=n;i++)
        {
            if(!vis[i] && i%p != 0)
            {
                cout<<i<<" ";
                vis[i] = 1;
                int last;
                for(int j=1;j;j++)
                {
                    if(p*j-i > n) break;
                    if(!vis[p*j-i] && p*j-i > 0)
                    {
                        cout<<p*j-i<<" ";
                        vis[p*j-i] = 1;
                        last = p*j-i;
                        for(int k=1;k;k++)
                        {
                            if(p*k-last > n) break;
                            if(p*k-last > 0 && !vis[p*k-last])
                            {
                                vis[p*k-last] = 1;
                                cout<<p*k-last<<" ";
                                last = p*k-last;
                            }
                        }
                    } 
                }
            }
        }
        for(int i=1;i<=n;i++) if(!vis[i]) cout<<i<<" ";
        cout<<endl;
    }
}
2023/8/21 11:07
加载中...