1366. 循环数

暴力思路,不断累加当前数,判断是否为循环数:

  • 每个数字位均不同
  • 数字位不能有(0)
  • 在所有数字上均停留一次后,回到出发点(最左边的数字),即每个数字位只能访问一次
bool used[10];  // 标记数字是否已使用
bool vis[10];  // 标记下标是否已访问
int m;

bool isunique(int n)
{
    memset(used,0,sizeof used);
    while(n)
    {
        int t=n%10;
        if(used[t]) return false;
        used[t]=true;
        n/=10;
    }
    return true;
}

bool circle(string s)
{
    memset(vis,0,sizeof vis);
    for(int i=0,j=0;i<s.size();i++)
    {
        int k=s[j]-'0';
        j=(j+k)%s.size();
        if(vis[j]) return false;
        vis[j]=true;
    }
    return true;
}

int main()
{
    cin>>m;

    while(true)
    {
        m++;
        if(isunique(m) && circle(to_string(m)))
        {
            cout<<m<<endl;
            break;
        }
    }

    //system("pause");
    return 0;
}

考虑到数字位各不相同的数在(2^{32})内只有(9!=362880)个,于是按从小到大顺序生成数字位各不相同的数,判断是否大于(m)且为循环数,第一个满足条件的数即为大于(m)的第一个循环数。

bool used[10];  // 标记数字是否已使用
bool vis[10];  // 标记位置是否已访问
int m;

bool circle(string s)
{
    memset(vis,0,sizeof vis);
    for(int i=0,j=0;i<s.size();i++)
    {
        int k=s[j]-'0';
        j=(j+k)%s.size();
        if(vis[j]) return false;
        vis[j]=true;
    }
    return true;
}

bool dfs(int u,int n,string path)
{
    if(u == n)
    {
        if(stoi(path) > m && circle(path))
        {
            cout<<path<<endl;
            return true;
        }
        return false;
    }

    for(int i=1;i<=9;i++)
        if(!used[i])
        {
            used[i]=true;
            if(dfs(u+1,n,path+char('0'+i))) return true;
            used[i]=false;
        }
    return false;
}

int main()
{
    cin>>m;

    int len=to_string(m).size();

    while(!dfs(0,len,"")) len++;

    //system("pause");
    return 0;
}
原文地址:https://www.cnblogs.com/fxh0707/p/14845974.html