hdu 1664如此爽的一道bfs+数论

来源:互联网 发布:阿里云服务器购买教程 编辑:程序博客网 时间:2024/06/07 16:22

这道题真的是要靠第三感觉,首先题目没有给定数字答案的大小限制,应该想到有条件可以限制这个数字的大小。

囧。。。。。。。。毕竟菜鸟,完全没想法。

ps:一个数论中的结论:对于任意的整数n,必然存在一个由不多于两个的数来组成的一个倍数。因为a,aa,aaa……取n+1个,则必有两个模n余数相同,相减即得n的倍数m。而m只由a、0组成。
先用一个数来搜答案,9种情况,已经搜到答案就输出,没有则再用两个数来搜答案,36种情况。当然,要注意答案必须是不同的数的个数最少,有不同答案的话再输出最小的。
#include <iostream>  #include <cstdio>  #include <cstring>  #include <string>  #define maxn 65540  using namespace std;    int n,m,mcnt,tcnt,h;  int a[5];  bool vis[maxn];  // 取余判重  string ans,tans;  struct Node  {      int d,val,pre; // val-有效值      int cnt;  } cur,now,q[maxn];    void getans(int k)// 递归得到ans 避免在结构体中添加string 每次操作string很拖时间  {      char c;      if(k==-1) return ;      else      {          getans(q[k].pre);          c=q[k].d+'0';          tans+=c;      }  }  bool bfs(int k)  {      int i,j,nval,ncnt,tval;      int head=0,tail=-1;      memset(vis,0,sizeof(vis));      for(i=1; i<=k; i++)      {          if(a[i])          {              cur.cnt=0;              cur.d=a[i];              cur.pre=-1;              cur.val=a[i]%n;              vis[cur.val]=1;              q[++tail]=cur;          }      }      while(head<=tail)      {          now=q[head];          nval=now.val;          ncnt=now.cnt;          if(ncnt>mcnt) break ;  // 剪枝          if(!nval)          {              h=head;              tcnt=ncnt;              return true ;          }          for(i=1; i<=k; i++)          {              tval=(nval*10+a[i])%n;              if(!vis[tval])              {                  vis[tval]=1;                  cur.cnt=ncnt+1;                  cur.d=a[i];                  cur.pre=head;                  cur.val=tval;                  q[++tail]=cur;              }          }          head++;      }      return false;  }  int main()  {      int i,j,flag;      while(scanf("%d",&n),n)      {          flag=0;          ans="xx";          mcnt=1000000000;          for(i=1; i<=9; i++)    // 先搜一个数能否组成n的倍数          {              a[1]=i;              if(bfs(1))              {                  tans="";                  getans(h);                  if(mcnt>tcnt||mcnt==tcnt&&ans>tans) // 注意怎么比较ans的大小                  {                      ans=tans;                      mcnt=tcnt;                  }              }          }          if(ans!="xx")          {              flag=1;              cout<<ans<<endl;          }          if(flag) continue ;          for(i=0; i<=9; i++)  // 再搜两个数          {              a[1]=i;              for(j=i+1; j<=9; j++)              {                  a[2]=j;                  if(bfs(2))                  {                      tans="";                      getans(h);                      if(mcnt>tcnt||mcnt==tcnt&&ans>tans)                      {                          ans=tans;                          mcnt=tcnt;                      }                  }              }          }          cout<<ans<<endl;      }      return 0;  } 


0 0
原创粉丝点击