暴力枚。枚举除数范围很容易算出来是1234~49383。因为49383*2=98766>98765。然后判断这十个数是不是0~9各出现一次就行。我用的是笨办法,用countt数组记录0~9每个数字出现的次数,一旦某个数已经出现就不符合。不过标程给的思路确实更精巧,用sprintf将这10位数输入到一个字符串中然后看是不是每个数出现了一次,但这样的办法速度好像会慢一点。贴一下自己写的10ms的程序吧。。笨办法居然出乎意料的快。。。
标程的网址:https://github.com/aoapc-book/aoapc-bac2nd/blob/master/ch7/UVa725.cpp
#include <cstdio>
#include <cstring>
#include <vector>
using namespace std;
typedef pair<int,int> int_pair;
vector<int_pair> ans[80];
int countt[10];
bool match(int a,int *countt)
{
for(int i=0;i<5;i++)
{
if(countt[a%10])
return false;
else
countt[a%10]++;
a/=10;
}
if(a>0) return false;
return true;
}
int main()
{
for(int i=1234;i<=49383;i++)
{
memset(countt,0,sizeof(countt));
if(match(i,countt))
{
for(int j=2;j<=79;j++)
{
int b[10];
for(int i=0;i<10;i++)
b[i]=countt[i];
if(match(i*j,b))
ans[j].push_back(int_pair(i*j,i));
}
}
}
int n,first=1;
while(scanf("%d", &n)&&n!=0)
{
if(first)
first=0;
else
printf("\n");
if(!ans[n].size())
printf("There are no solutions for %d.\n",n);
else
{
for(int i=0;i<ans[n].size();i++)
{
printf("%05d / %05d = %d\n", ans[n][i].first,ans[n][i].second,n);
}
}
}
return 0;
}