BFS+余数判重+数论 hdu-1664-Different Digits

来源:互联网 发布:java.util.stream jar 编辑:程序博客网 时间:2024/06/05 05:35

题目链接:

http://acm.hdu.edu.cn/showproblem.php?pid=1664

题目意思:

给一个n,让你找出含不同数字最少的n的倍数,如果含不同数字相同,则输出最小的。

解题思路:

根据数论里面的知识点:

对于任意的整数n,必然存在一个由不多于两个的数来组成的一个倍数。因为aaaaaa……n+1个,则由鸽笼原理,必有两个模n余数相同,相减即得n的倍数m。而m只由a0组成。

对于余数相同的情况,数位少的含不同数字的个数肯定不超过数位多的,所以可以用余数判重。

先扫描一位的情况,然后在考虑两位的情况。

代码:

#include<iostream>#include<cmath>#include<cstdio>#include<cstdlib>#include<string>#include<cstring>#include<algorithm>#include<vector>#include<map>#include<set>#include<stack>#include<list>#include<queue>#define eps 1e-6#define INF 0x1f1f1f1f#define PI acos(-1.0)#define ll __int64#define lson l,m,(rt<<1)#define rson m+1,r,(rt<<1)|1#pragma comment(linker, "/STACK:1024000000,1024000000")using namespace std;#define Maxn 70000/*freopen("data.in","r",stdin);freopen("data.out","w",stdout);*/bool vis[Maxn];struct Inf{   int m,pre,d,cnt;}myq[Maxn]; //余数不同的入队,最多只有65535中情况int n,save[5],nn,mm;string ans,temp;void gettemp(int x) //递归输出,免得用string超时{   if(x==-1)      return ;   gettemp(myq[x].pre);   temp+=(myq[x].d+'0');   return ;}void bfs(){   memset(vis,false,sizeof(vis));   int head=0,tail=-1;   for(int i=1;i<=nn;i++)   {      if(!save[i]) //第一位         continue;      Inf cur;      cur.pre=-1;      cur.d=save[i];      cur.m=save[i]%n;      cur.cnt=1;      vis[cur.m]=true;      myq[++tail]=cur;   }   while(head<=tail)   {      int h=head;head++;      if(myq[h].cnt>mm) //剪枝,不可能小于ans.         return ;      if(!myq[h].m) //如果存在,则跳出,后面肯定比自己大,不管      {         temp="";         gettemp(h);         if(myq[h].cnt<mm) //位数少         {            ans=temp;            mm=myq[h].cnt;         }         else if(myq[h].cnt==mm) //位数相同,值小         {            if(temp<ans)               ans=temp;         }         return ;      }      for(int i=1;i<=nn;i++)      {         int xx=(myq[h].m*10+save[i])%n;         if(vis[xx]) //余数判重            continue;         vis[xx]=true;         Inf tt;         tt.m=xx,tt.cnt=myq[h].cnt+1;         tt.d=save[i],tt.pre=h; //记录前一个,递归输出         myq[++tail]=tt;      }   }}int main(){   while(scanf("%d",&n)&&n)   {      nn=1;      mm=INF;     // printf(":%d\n",mm);      for(int i=1;i<=9;i++)      {         save[1]=i;         bfs();      }      //printf("mm:%d\n",mm);      //cout<<ans<<endl;      if(mm!=INF) //只用一个数字就可以得到,      {         cout<<ans<<endl;         continue;      }      nn=2;      for(int i=0;i<=9;i++)      {         save[1]=i;         for(int j=i+1;j<=9;j++)         {            save[2]=j;            bfs(); //必须用两个         }      }      cout<<ans<<endl;   }   return 0;}




原创粉丝点击