HDU 1664 Different Digits

举报
Linux猿 发表于 2021/08/04 23:34:10 2021/08/04
【摘要】 题目链接~~> 做题感悟:                这道题是在学长讲完取余的方法后才做的,开始用的以前用的方法,结果超内存,然后用了 C++ 的 string 类后又超时,真无语!经过这一题,明显发现自己掌握的知识太少了。...

题目链接~~>

做题感悟:

               这道题是在学长讲完取余的方法后才做的,开始用的以前用的方法,结果超内存,然后用了 C++ 的 string 类后又超时,真无语!经过这一题,明显发现自己掌握的知识太少了。

题意:

         给你一个 n ,让你找它的倍数,要有最少的不同的数字,如果不同的数字一样,输出数小的那个。

解题思路:

              首先要用到超级密码那题的取余思想,其次还有一点,任何一个数都可以用两种不同的数字表示倍数(数论中的定理)。用 string 类时广搜到结果时要回溯的方法(具体看代码,提交用C++)。

代码:


  
  1. #include<stdio.h>
  2. #include<string.h>
  3. #include<iostream>
  4. #include<string>
  5. #include<queue>
  6. using namespace std ;
  7. #define MX 65536
  8. int n,num,mx ;
  9. int g[5] ;
  10. bool vis[MX],flag ;
  11. struct zhang
  12. {
  13. int x,m,cnt,pre ;// pre 记录父亲节点
  14. }q[MX] ;
  15. string str,key ;
  16. void gettemp(int k) // 回溯复制到 str ,如果不用会超时
  17. {
  18. if(k==-1)
  19. return ;
  20. gettemp(q[k].pre) ; // 找父亲
  21. str+=(q[k].x+'0') ;
  22. return ;
  23. }
  24. int bfs()
  25. {
  26. int head=0,tail=-1 ;
  27. memset(vis,false,sizeof(vis)) ;
  28. for(int i=0 ;i<num ;i++)
  29. {
  30. if(!g[i]) continue ;
  31. zhang current ;
  32. current.pre=-1 ;
  33. current.x=g[i] ; // 存放的数
  34. current.m=g[i]%n ; // 存余数
  35. current.cnt=1 ; // 记录个数
  36. vis[current.m]=true ;
  37. q[++tail]=current ;
  38. }
  39. while(head<=tail)
  40. {
  41. int h=head ;head++ ;
  42. if(q[h].cnt>mx) // 当大于最少个数时不进行下去
  43. continue ;
  44. if(!q[h].m) // 找到满足的解
  45. {
  46. str="" ;
  47. gettemp(h) ;
  48. if(q[h].cnt<mx)
  49. {
  50. key=str ;
  51. mx=q[h].cnt ;
  52. }
  53. else if(q[h].cnt==mx)
  54. {
  55. if(str<key)
  56. key=str ;
  57. }
  58. return true ;
  59. }
  60. for(int i=0 ;i<num ;i++)
  61. {
  62. int mod=(q[h].m*10+g[i])%n ;
  63. if(vis[mod]) continue ;
  64. vis[mod]=true ;
  65. zhang tep ;
  66. tep.m=mod ; tep.cnt=q[h].cnt+1 ;
  67. tep.x=g[i] ; tep.pre=h ; // 记录前一个值,为了不超时
  68. q[++tail]=tep ;
  69. }
  70. }
  71. return false ;
  72. }
  73. int main()
  74. {
  75. int i,j ;
  76. while(scanf("%d",&n)!=EOF)
  77. {
  78. if(!n) break ;
  79. num=1 ;mx=9999999 ;flag=false ;
  80. key="" ;
  81. for(i=1 ;i<=9 ;i++)
  82. {
  83. g[0]=i ;
  84. if(bfs())
  85. flag=true ;
  86. }
  87. if(flag)
  88. {
  89. cout<<key<<endl ;
  90. continue ;
  91. }
  92. num=2 ;
  93. for(i=0 ;i<=9 ;i++)
  94. {
  95. g[0]=i ;
  96. for(j=i+1 ;j<=9 ;j++)
  97. {
  98. g[1]=j ;
  99. bfs() ;
  100. }
  101. }
  102. cout<<key<<endl ;
  103. }
  104. return 0 ;
  105. }


 

 

文章来源: blog.csdn.net,作者:Linux猿,版权归原作者所有,如需转载,请联系作者。

原文链接:blog.csdn.net/nyist_zxp/article/details/16951963

【版权声明】本文为华为云社区用户转载文章,如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。