题意:给出一个指数p,问1~p-1的数是否存在这样一个序列:a[i+1]=(a[i] * 2) % p,或者a[i+1]=(a[i] * 3)%p,如果存在打印这个序列,否则输出-1;

这道题可以用DFS做,并不会超时,也可以用非递归方法做,非递归方法我也不知道为什么会对,下面是两种方法的代码:

递归方法:这种方法看起来比较麻烦,可要是知道思路,还是很好写的。
/*少说话,多做事*/
#include <cstdio>
#include <cstring>
#include <string>
#include <cmath>
#include <iostream>
#include <algorithm>
#include <vector>
#include <stack>
#include <sstream>
#include <map>
#include <set>
#include <queue>
#include <stdlib.h>

typedef long long ll;
using namespace std;
int flag[1000006];
int a[1000006];
int cnt;
int n;
int flag2;
void DFS(int x)
{
    if(cnt==n-1||flag2==1) //如果满足条件就返回
    {
        flag2=1;
        return;
    }
    if(flag[x*2%n]==0&&x*2%n!=0)
    {
        flag[x*2%n]=1;
        cnt++;
        a[cnt]=x*2%n;
        DFS(x*2%n);
        flag[x*2%n]=0;
        cnt--;
    }
    else if(flag[x*3%n]==0&&x*3%n!=0)
    {
        flag[x*3%n]=1;
        cnt++;
        a[cnt]=x*3%n;
        DFS(x*3%n);
        flag[x*3%n]=0;
        cnt--;
    }
}
int main()
{
    int T;
    cin >> T;
    while (T--)
    {
        scanf("%d", &n);
        memset(a, 0, sizeof(a)); //一开始的a全是0
        memset(flag, 0, sizeof(flag)); //一开始的flag全是0
        a[1]=1;
        flag[1]=1;
        cnt=1;
        flag2=0;
        DFS(1);
        if(flag2==1)
        {
            for (int i=1;i<=n-1;i++)
            {
                cout << a[i] << " ";
            }
        }
        else cout << "-1" ;
        cout << endl;
    }
}

下面是非递归方法:
/*少说话,多做事*/
#include <cstdio>
#include <cstring>
#include <string>
#include <cmath>
#include <iostream>
#include <algorithm>
#include <vector>
#include <stack>
#include <sstream>
#include <map>
#include <set>
#include <queue>
#include <stdlib.h>

typedef long long ll;
using namespace std;
int flag[1000006];
int a[1000006];
int main()
{
    int T;
    int n,  co;
    cin >> T;
    while (T--)
    {
        scanf("%d", &n);
        memset(a, 0, sizeof(a)); //一开始的a全是0
        memset(flag, 0, sizeof(flag)); //一开始的flag全是0
        a[1] = 1; //第一个数为1
        flag[1] = 1;//将1标记一下
        co = 1;
        while (co < n - 1)
        {
            int k = a[co] * 2 % n;
            if (flag[k] == 1) k = a[co] * 3 % n; //如果k被标记了,也就是不能是2倍,那么可能是3倍
            if (flag[k] == 1) break;             //如果2倍和3倍都被标记了,那么最后直接break掉就可以了
            a[++co] = k;
            flag[k] = 1; //将k标记一下
        }
        if (co == n - 1) //如果有n-1个数,那么说明可以进行这样标记,即先找2的倍数,然后再找3的倍数
        {
            for (int i = 1; i < n; i++) printf("%d ", a[i]); //输出上述记录再a数组中的数
        }
        else printf("-1"); //如果不存在,那么直接输出-1
        cout << endl;
    }
}