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 long using 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)*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); }话说阳哥的代码又快又小又短