您的位置:首页 > 其它

数学专项number_theory:LA 3262

2013-10-22 12:25 351 查看
题意就是找出n(1<=n<=65536)的一个倍数,要求组成该数的不同数(0-9)最少,多解时,输出最小的。学过离散的都知道,通过鸽巢原理,组成解的不同数最多为2,且每种组合最多经历n个状态,所以暴力枚举所有组合的复杂度为65536*100,完全可以接受。

这里需要自己手写一个高精度类以比较大数,先枚举一个数的情况,若不存在,再枚举二个数的情况即可。

#include <iostream>
#include <cstdio>
#include <cstring>
#include <queue>
using namespace std;
const int maxn=66000;
struct bign
{
int len,s[maxn];
bign(){memset(s,0,sizeof(s));len=1;}
bign(int l,int c)
{
len=l;
for(int i=0;i<len;i++) s[i]=c;
}
bool operator<(const bign& tmp) const
{
if(len<tmp.len) return true;
else if(len>tmp.len) return false;
else
{
for(int i=0;i<len;i++)
if(s[i]>tmp.s[i]) return false;
else if(s[i]<tmp.s[i]) return true;
}
return true;
}
void print()
{
for(int i=0;i<len;i++)
printf("%d",s[i]);
puts("");
}
};
int n;
int vis[maxn],dir[maxn],pre[maxn],d[maxn];
bign bfs(int x,int y)
{
memset(vis,0,sizeof(vis));
queue<int> q;
bign tmp;
if(x)
{
q.push(x%n);
vis[x%n]=1;
dir[x%n]=0;
d[x%n]=1;
}
if(y)
{
q.push(y%n);
vis[y%n]=1;
dir[y%n]=1;
d[y%n]=1;
}
while(!q.empty())
{
int u=q.front();q.pop();
int v1=(u*10+x)%n;
if(!vis[v1])
{
vis[v1]=1;
q.push(v1);
dir[v1]=0;
d[v1]=d[u]+1;
pre[v1]=u;
if(v1==0)
{
vis[0]=1;
tmp.len=d[v1];
int r=0;
for(int i=d[v1]-1;i>=0;i--)
{
tmp.s[i]=dir[r]?y:x;
r=pre[r];
}
return tmp;
}
}
int v2=(u*10+y)%n;
if(!vis[v2])
{
vis[v2]=1;
q.push(v2);
dir[v2]=1;
d[v2]=d[u]+1;
pre[v2]=u;
if(v2==0)
{
vis[0]=1;
tmp.len=d[v2];
int r=0;
for(int i=d[v2]-1;i>=0;i--)
{
tmp.s[i]=dir[r]?y:x;
r=pre[r];
}
return tmp;
}
}
}
return tmp;
}
int main()
{
while(scanf("%d",&n) && n)
{
bign ans;int flag=0;
for(int i=1;i<10;i++)
{
memset(vis,0,sizeof(vis));
int s=0,p=i,c=0;
do
{
s=(s+p)%n;
//cout<<i<<" "<<s<<endl;
if(vis[s]) break;
vis[s]=1;
p=p*10%n;
c++;
} while(s);
if(s==0)
{
bign tmp(c,i);
//                cout<<c<<" "<<i<<endl;
//                tmp.print();
if(flag)
{
if(tmp<ans) ans=tmp;
}
else
{
flag=1;
ans=tmp;
}
}
}
if(flag)
{
//cout<<ans.len<<endl;
ans.print();
continue;
}
for(int i=0;i<10;i++)
for(int j=i+1;j<10;j++)
{
bign tmp=bfs(i,j);
if(!vis[0]) continue;
//cout<<i<<" "<<j<<" ";
if(flag)
{
if(tmp<ans) ans=tmp;
}
else
{
flag=1;
ans=tmp;
}
//ans.print();
}
ans.print();
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: