数论-魔幻六位数

来源:互联网 发布:淘宝收费推广有哪些 编辑:程序博客网 时间:2024/06/09 16:48

http://prayer.hustoj.com/problem.php?id=1733
感觉就是很难的那种题;
网上搜不到题解;
自己又笨;
只能到处问大神;
我直接说思路了;


显然的,我们发现暴力很萎;
虽然可以剪枝,但太复杂;
我们就枚举最后一位,因为最后一位一定不会进位,所以我们就可以得出所有的数字了;
然后是轮换排列,所以每个位子上会每个数会出现一次;
那我们把枚举最后一位时所得到的一组数字加起来;
这个值再乘以11111..;
我们就得到了把轮换的那几个数字全部加起来所的的结果;
比如:
142857+428571+285714+…=(1+4+2+8+5+7)*111111
然后我们可以判断一下这个结果能否整除(1+2+…+m)
可以整除的话那我们就得到一个解,再判断一下这个解的各位数字是不是原来算出来的那组数字;
是的话就是了;
关于进制的问题瞎搞就好啦;
比如那个111111是n进制的;

#include<iostream>#define Ll long longusing namespace std;Ll n,m,a[20],q[20],tot;bool b[20];char s[26]="0123456789ABCDEF";Ll turn(Ll x){    Ll ans=0,k=1;    while(x){ans+=(x%10)*k;k*=n;x/=10;}    return ans;}void pd(Ll x){    Ll sum=0,y=0;    for(int i=1;i<=m;i++){y=x*i%n;sum+=y;a[i]=y;b[i]=0;}    y=1;    for(int i=1;i<m;i++)y=y*10+1;    y=turn(y)*sum;    if(y%(m*(m+1)/2))return;    y/=m*(m+1)/2;    tot=0;    while(y)q[++tot]=y%n,y/=n;      if(tot!=m)return;    for(int i=1;i<=m;i++){        bool p=0;        for(int j=1;j<=m;j++)if(a[j]==q[i]&&!b[j]){b[j]=1;p=1;break;}        if(!p)return;    }    while(tot)cout<<s[q[tot--]];}int main(){    cin>>n>>m;    for(int i=1;i<n;i++)pd(i);}

话说阳哥的代码又快又小又短
这里写图片描述

0 0
原创粉丝点击