UVA - 10825 Anagram and Multiplication

题目链接:http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=34594

有一个m位n进制的数,它的特性是这个数依次乘以2,3.......m,最后得到的数仍然为这个数的某个排列,例如:

有一个6位十进制数:142857

2 x 142,857 = 285,714
3 x 142,857 = 428,571
4 x 142,857 = 571,428
5 x 142,857 = 714,285
6 x 142,857 = 857,142

那么输入6 10就应该有输出142857(假定这样的数有且仅有一个),如果没有,输出not find

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
using namespace std;

int m,n,a[10],b[10],p[10],aa[10],ans[10];

bool ak()
{
    int c[10];
    for(int i=0;i<m;i++) c[i]=b[i]=a[p[i]];   //生成待检测的数
    for(int k=2;k<=m;k++)
    {
        for(int i=0;i<m;i++)
        {
            c[i+1]+=(c[i]+b[i])/n;  //不直接乘以k是因为每次c[i],b[i]才不方便初始到原有状 态
            c[i]=(c[i]+b[i])%n;
        }
        for(int i=0;i<m;i++) aa[i]=c[i];
        sort(aa,aa+m);sort(ans,ans+m);        //检验是否是原来的数的某个排列
        for(int i=0;i<m;i++)
        if(aa[i]!=ans[i]) return 0;
    }
    return 1;
}

bool dfs(int cur)
{
    if(cur==m) return ak();
    for(int i=cur;i<m;i++)
    {
     swap(p[cur],p[i]);
     if(dfs(cur+1)) return 1;
     swap(p[cur],p[i]);
    }
    return 0;
}

bool check(int x)
{
    int t=0;
    for(int i=0;i<m;i++)
    {
        t=(t+x)%n;
        a[i]=t;
        p[i]=i;
        ans[i]=t;
    }
    return dfs(0);
}

int main()
{
    while(scanf("%d%d",&m,&n)!=EOF&&m)
    {
     int flag=0;
     for(int i=1;i<n;i++)
     {
         if(check(i))
         {
             flag=1;
             break;
         }
     }
     if(!flag)
        printf("Not found.\n");
     else
     {
         printf("%d",b[m-1]);
         for(int i=m-2;i>=0;i--)
            printf(" %d",b[i]);
         puts("");
     }
    }
    return 0;
}
View Code

 

posted @ 2015-10-08 17:35  江南何采莲  阅读(243)  评论(0编辑  收藏  举报