NYOJ 929 密码宝盒 || HDU 1226 超级密码

举报
Linux猿 发表于 2021/08/04 23:18:29 2021/08/04
【摘要】 题目链接~~> 做题感悟:               开始听了学长讲课后在杭电上做过这个题,之后又在比赛时遇见,当时有点不淡定 RE 了三次,开始以为数组开小了后来才发现没有考虑到 n = 0 ;的情况,以后即使遇到原题也应该认真读题。...

题目链接~~>

做题感悟:

              开始听了学长讲课后在杭电上做过这个题,之后又在比赛时遇见,当时有点不淡定 RE 了三次,开始以为数组开小了后来才发现没有考虑到 n = 0 ;的情况,以后即使遇到原题也应该认真读题。

题意:

         给你一个 n ,m个C进制的数。让你组合成最小的数字是 n 的倍数。

解题思路:

               这需要数学知识,r = k ( mod n ) 则 ( k * p + a ) ( mod c ) = ( r * p + a ) ( mod  n ) ;余数出现过如果再次出现就不用再次使用。

代码(本人):


  
  1. #include<stdio.h>
  2. #include<string.h>
  3. #include<algorithm>
  4. #include<queue>
  5. using namespace std ;
  6. int n,m,c ;
  7. int g[20] ;
  8. bool vis[10000] ;
  9. struct zhang
  10. {
  11. int x,y[505],num,bu ;
  12. } ;
  13. bool bfs()
  14. {
  15. int i,j ;
  16. queue<zhang>q ;
  17. zhang cur,next ;
  18. memset(vis,false,sizeof(vis)) ;
  19. cur.x=0 ;
  20. cur.num=0 ;
  21. cur.bu=0 ;
  22. q.push(cur) ;
  23. while(!q.empty())
  24. {
  25. cur=q.front() ;
  26. q.pop() ;
  27. for(i=0 ;i<n ;i++)
  28. {
  29. next.x=cur.x*c+g[i] ;
  30. if(!next.x) continue ; // 前缀不能是 0
  31. next.bu=cur.bu+1 ;
  32. next.num=cur.num+1 ;
  33. next.x=next.x%m ;
  34. if(vis[next.x]||next.num>500) continue ; // 如果余数出现过或长度大于 500 不继续下去
  35. vis[next.x]=1 ;
  36. for(j=0 ;j<cur.num ;j++)
  37. next.y[j]=cur.y[j] ;
  38. next.y[cur.num]=g[i] ;
  39. if(!next.x) // 找到解输出
  40. {
  41. for(j=0 ;j<next.num ;j++)
  42. if(next.y[j]>9)
  43. printf("%c",next.y[j]+55) ;
  44. else printf("%d",next.y[j]) ;
  45. printf("\n") ;
  46. return true ;
  47. }
  48. q.push(next) ;
  49. }
  50. }
  51. return false ;
  52. }
  53. int main()
  54. {
  55. int T,i ;
  56. char ch ;
  57. scanf("%d",&T) ;
  58. while(T--)
  59. {
  60. scanf("%d%d%d",&m,&c,&n) ;
  61. for(i=0 ;i<n ;i++)
  62. {
  63. getchar() ;
  64. scanf("%c",&ch) ;
  65. if(ch>='A'&&ch<='F')
  66. g[i]=ch-55 ;
  67. else g[i]=ch-'0' ;
  68. }
  69. sort(g,g+n) ; // 排序让第一个找到的是最小的
  70. if(!m) // 0 需要特判一下
  71. {
  72. if(!g[0])
  73. printf("0\n") ;
  74. else
  75. printf("give me the bomb please\n") ;
  76. continue ;
  77. }
  78. if(!bfs())
  79. printf("give me the bomb please\n") ;
  80. }
  81. return 0 ;
  82. }

代码:


  
  1. #include<stdio.h>
  2. #include<string.h>
  3. #include<queue>
  4. #include<algorithm>
  5. #include<iostream>
  6. #define MX 50005
  7. using namespace std ;
  8. int n,c,m ;
  9. int g[18] ;
  10. bool vis[MX] ;
  11. struct zhang
  12. {
  13. int x,m,pre,cnt ;
  14. }q[MX] ;
  15. void gettep(int k)
  16. {
  17. if(k==-1)
  18. return ;
  19. gettep(q[k].pre) ;
  20. if(q[k].x>=10)
  21. printf("%c",q[k].x+55) ;
  22. else printf("%c",q[k].x+'0') ;
  23. return ;
  24. }
  25. int bfs()
  26. {
  27. int head=0,tail=-1 ;
  28. memset(vis,false,sizeof(vis)) ;
  29. for(int i=0 ;i<m ;i++)
  30. {
  31. if(!g[i]) continue ;
  32. zhang next ;
  33. next.pre=-1 ;
  34. next.x=g[i] ;
  35. next.m=g[i]%n ;
  36. vis[next.m]=true ;
  37. next.cnt=1 ;
  38. q[++tail]=next ;
  39. }
  40. while(head<=tail)
  41. {
  42. int h=head ;head++ ;
  43. if(q[h].cnt>500) continue ;
  44. if(!q[h].m)
  45. {
  46. gettep(h) ;
  47. return true ;
  48. }
  49. for(int i=0 ;i<m ;i++)
  50. {
  51. int key=(q[h].m*c+g[i])%n ;
  52. if(vis[key]) continue ;
  53. vis[key]=true ;
  54. zhang tep ;
  55. tep.m=key ; tep.x=g[i] ;
  56. tep.pre=h ; tep.cnt=q[h].cnt+1 ;
  57. q[++tail]=tep ;
  58. }
  59. }
  60. return false ;
  61. }
  62. int main()
  63. {
  64. int T,i ;
  65. char ch ;
  66. scanf("%d",&T) ;
  67. while(T--)
  68. {
  69. scanf("%d%d%d",&n,&c,&m) ;
  70. for(i=0 ;i<m ;i++)
  71. {
  72. cin>>ch ;
  73. if(ch>='A'&&ch<='F')
  74. g[i]=ch-55 ;
  75. else g[i]=ch-'0' ;
  76. }
  77. sort(g,g+m) ;
  78. if(!n)
  79. {
  80. if(!g[0]) printf("0") ;
  81. else printf("So Sorry.") ;
  82. puts("") ;
  83. continue ;
  84. }
  85. if(!bfs())
  86. printf("So Sorry.") ;
  87. puts("") ;
  88. }
  89. return 0 ;
  90. }

优代码:


  
  1. #include <queue>
  2. #include <string>
  3. #include <stdio.h>
  4. #include <string.h>
  5. #include <algorithm>
  6. using namespace std;
  7. const int N = 5005;
  8. bool vis[N];
  9. string ans;
  10. int a[17],pre[N],ansAt[N],n,m,c;
  11. int ctoi(char c)
  12. {
  13. return c >= '0' && c <= '9' ? c - '0' : c - 'A' + 10;
  14. }
  15. char itoc(int i)
  16. {
  17. return i <= 9 ? i + '0' : i + 'A' - 10;
  18. }
  19. bool bfs()
  20. {
  21. queue<int> q;
  22. q.push(0);
  23. while(!q.empty())
  24. {
  25. int cur = q.front();q.pop();
  26. for(int i=0;i<m;i++)
  27. {
  28. int nxt = (cur * c + a[i]) % n;
  29. if(cur == 0 && a[i] == 0 || vis[nxt])
  30. continue;
  31. vis[nxt] = true;
  32. ansAt[nxt] = a[i];
  33. pre[nxt] = cur;
  34. if(nxt == 0)
  35. return true;
  36. q.push(nxt);
  37. }
  38. }
  39. return false;
  40. }
  41. bool check()
  42. {
  43. ans = "";
  44. int p = 0;
  45. do
  46. {
  47. ans += itoc(ansAt[p]);
  48. p = pre[p];
  49. }while(p);
  50. return (int)ans.size() <= 500;
  51. }
  52. int main()
  53. {
  54. int T;
  55. scanf("%d",&T);
  56. while(T--)
  57. {
  58. memset(vis,false,sizeof(vis));
  59. scanf("%d%d%d",&n,&c,&m);
  60. for(int i=0;i<m;i++)
  61. {
  62. char num[3];
  63. scanf("%s",num);
  64. a[i] = ctoi(num[0]);
  65. }
  66. sort(a,a+m);
  67. if(n == 0)
  68. {
  69. puts(a[0] == 0 ? "0" : "So Sorry.");
  70. continue;
  71. }
  72. if(bfs() && check())
  73. {
  74. for(int i=(int)ans.size()-1;i>=0;i--)
  75. putchar(ans[i]);
  76. puts("");
  77. }
  78. else
  79. puts("So Sorry.");
  80. }
  81. return 0;
  82. }
  83.  

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

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

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

评论(0

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

全部回复

上滑加载中

设置昵称

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

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

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