链接
https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=1766
题解
看了题之后本来是想弃疗的,但是我稍微回去读了下题,就发现了一件神奇的事情
2 x 142,857 = 285714
3 x 142,857 = 428571
4 x 142,857 = 571428
5 x 142,857 = 714285
6 x 142,857 = 857142
仔细看看右边
285714
428571
571428
714285
857142
有没有发现,
的后面始终是
?
再看看呢?这些数的相对位置都没有改变啊
也就是说,由原来的数字右移
次,就能得到等号右边的数字
那么也就是说所有等号右边的数字,最后一位都是不同的,且恰好对应这
位数字!
那我就枚举最后一位,然后乘上
得到其它位上的数字,再瞎排列一下,然后写个
验证下,不就完了么?
当然以上结论是观察得出的,还需要进一步证明。
我的数学能力有限,实在想不出,若有想法欢迎在评论区留言
代码
//瞎猜题
#include <cstdio>
#include <algorithm>
#include <cctype>
#include <cstring>
#define maxn 500
#define cl(x) memset(x,0,sizeof(x))
using namespace std;
int read(int x=0)
{
char c, f=1;
for(c=getchar();!isdigit(c) and c^1;c=getchar())if(c=='-')f=-1;
for(;isdigit(c);c=getchar())x=(x<<1)+(x<<3)+c-48;
return f*x;
}
int num[maxn], n, m, used[maxn], Exit;
bool check()
{
int i, j, tmp[maxn], cnt[maxn], res;
for(i=2;i<=m;i++)
{
cl(tmp), cl(cnt);
for(j=1;j<=m;j++)tmp[j]=num[j];
for(j=1;j<=m;j++)tmp[j]*=i;
for(j=1;j<m;j++)tmp[j+1]+=tmp[j]/n, tmp[j]%=n;
for(j=1;j<=m;j++)cnt[num[j]]=1;
for(j=1,res=m;j<=m;j++)if(tmp[j]<maxn and cnt[tmp[j]]==1)cnt[tmp[j]]=0, res--;
if(res)return false;
}
return true;
}
void dfs(int deep)
{
int i;
if(deep>m)
{
if(check())
{
printf("%d",num[m]);
for(i=m-1;i;i--)printf(" %d",num[i]);
printf("\n");
Exit=1;
}
return;
}
for(i=2;i<=m and !Exit;i++)
{
if(!used[num[1]*i%n])
{
num[deep]=num[1]*i%n;
used[num[1]*i%n]=1;
dfs(deep+1);
used[num[1]*i%n]=0;
}
}
}
void solve()
{
int i;
Exit=0;
for(i=1;i<n;i++)
{
num[1]=i;
dfs(2);
if(Exit)break;
}
if(i==n)printf("Not found.\n");
}
int main()
{
for(m=read(), n=read();n;m=read(), n=read())solve();
return 0;
}