题目
UVa 10825 Anagram and Multiplication
题解
终于又做出来一道好开心qwq。因为我一激动发现如果枚举末位的话,分别乘1~m之后末位上的所有数字就会是答案的一个排列,然后根据这个去枚举答案,然后check一下就行了。复杂度的话好像比别人高一点,人傻自带9的常数_ (:зゝ∠) _。O(n* m! * m^2)—-(m次乘法,高精乘低精O(m)),其实算算对于单组数据的话,,卧槽怎么1e7了,我还是去学习一下更优秀的算法吧qwq
注:这题行末多空格会PE。。。我的1A啊qwq
代码
//QWsin
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
const int maxm=10;
const int maxn=400+10;
int n,m,num[maxm],id[maxm];
int a[maxm],b[maxm],cnt[maxn],cnt2[maxn];
inline int check(int *a)
{
if(!a[m]) return 0;
for(int i=1;i<=m;++i) ++cnt[a[i]];
int ret=1;
for(int i=2;i<=m;++i)
{
for(int j=1;j<=m+1;++j) b[j]=0;
for(int j=1;j<=m;++j)
{
b[j]+=a[j]*i;
b[j+1]+=b[j]/n;
b[j]%=n;
}
if(b[m+1]) {ret=0;break;}
for(int j=1;j<=m;++j) ++cnt2[b[j]];
int ok=1;
for(int j=1;j<=m;++j) if(cnt2[b[j]]!=cnt[b[j]]) {ok=0;break;}
for(int j=1;j<=m;++j) --cnt2[b[j]];
if(!ok) {ret=0;break;}
}
for(int i=1;i<=m;++i) --cnt[a[i]];
return ret;
}
inline void solve()
{
for(int x=1;x<n;++x)//枚举末位
{
for(int i=1;i<=m;++i) num[i]=x*i%n;
for(int i=1;i<=m;++i) id[i]=i;
do{
for(int i=1;i<=m;++i) a[id[i]]=num[i];
if(check(a))
{
printf("%d",a[m]);
for(int i=m-1;i>=1;--i) printf(" %d",a[i]);
printf("\n");return ;
}
}while(next_permutation(id+1,id+m+1));
}
printf("Not found.\n");
}
int main()
{
while(scanf("%d%d",&m,&n)==2){
if(!m&&!n) break;
solve();
}
return 0;
}