hdu1664 Different Digits

求出n的倍数m,要求m使用的不同数字最少,且最小。

一开始不知道怎么搜,因为不知道m由多少个不同的数字组成。

然后百度了一下,看到和数论有关。

m可能使用的数字的个数可能为一个或者两个

a,aa,aaa....n+1个a, 将这些数%n,那么肯定有两个余数相等,抽屉原理。那么这两个数相减,得到的数肯定是n的倍数,且这两个数由a和0组成。

所以就知道怎么搜了,先搜m由一个数组成的情况,如果不存在,那么就搜两个数组成的情况,要注意全部搜完,因为题目要求m最小。

  1 #include <stdio.h>
  2 #include <string.h>
  3 #include <queue>
  4 #include <iostream>
  5 #include <string>
  6 using namespace std;
  7 struct node
  8 {
  9     int res;
 10     string str;
 11 };
 12 bool vis[66666];;
 13 int digit;
 14 int cnt;
 15 string ans;
 16 bool find_;
 17
 18 void bfs1(int n)
 19 {
 20     int res;
 21     int k;
 22     for(int i=1; i<=9; ++i)
 23     {
 24         k = 1;
 25         res = i % n;
 26         memset(vis,0,sizeof(vis));
 27         while(!vis[res] && res!=0)
 28         {
 29             vis[res] = true;
 30             res = (res * 10 + i) % n;
 31             k++;
 32         }
 33         if(res==0)
 34         {
 35             if(cnt==0)
 36             {
 37                 cnt = k;
 38                 digit = i;
 39             }
 40             else if(cnt>k)
 41             {
 42                 cnt = k;
 43                 digit = i;
 44             }
 45         }
 46     }
 47 }
 48 void bfs2(int i, int j,int n)
 49 {
 50     memset(vis,0,sizeof(vis));
 51     queue<node> q;
 52     node cur,tmp;
 53     if(i!=0)
 54     {
 55         cur.res = i % n;
 56         cur.str = (char)(i+‘0‘);
 57         q.push(cur);
 58     }
 59     cur.res = j % n;
 60     cur.str = (char)(j+‘0‘);
 61     q.push(cur);
 62     while(!q.empty())
 63     {
 64         cur = q.front(); q.pop();
 65         if(cur.res ==0)
 66         {
 67             if(!find_)
 68             {
 69                 ans = cur.str;
 70                 find_ = true;
 71             }
 72             else if(cur.str.size() < ans.size())
 73                 ans = cur.str;
 74             else if(cur.str.size()==ans.size() && cur.str < ans)
 75                 ans = cur.str;
 76             return;
 77
 78         }
 79         if(find_ && cur.str.size() >= ans.size())
 80             continue;
 81         tmp.res = (cur.res * 10 + i) % n;
 82         if(!vis[tmp.res])
 83         {
 84             vis[tmp.res] = true;
 85             tmp.str = cur.str + (char)(i+‘0‘);
 86
 87                 q.push(tmp);
 88         }
 89         tmp.res = (cur.res * 10 + j) % n;
 90         if(!vis[tmp.res])
 91         {
 92             vis[tmp.res] = true;
 93             tmp.str = cur.str + (char)(j+‘0‘);
 94                 q.push(tmp);
 95         }
 96     }
 97 }
 98
 99 int main()
100 {
101     int n,i,j;
102     while(scanf("%d",&n),n)
103     {
104         find_ = false;
105         cnt = 0;
106         bfs1(n);
107         if(cnt!=0)
108             for(i=0; i<cnt; ++i)
109                 printf("%d",digit);
110         else
111         {
112             for(i=0; i<=9; ++i)
113                 for(j=i+1; j<=9; ++j)
114                 {
115                     bfs2(i,j,n);
116                 }
117             cout<<ans;
118         }
119         puts("");
120     }
121 }
时间: 2024-07-30 15:25:52

hdu1664 Different Digits的相关文章

POJ 3373 Changing Digits

题目大意: 给出一个数n,求m,使得m的长度和n相等,能被k整除.有多个数符合条件输出与n在每位数字上改变次数最小的.改变次数相同的输出大小最小的.  共有两种解法:DP解法,记忆化搜索的算法. 以后会更新记忆化搜索. 1.DP解法: 解题思路: DP[i][j]表示数n的前i位除以k余j最小改变几位. DP[len][0]就表示数n被k整除最小改变几位. 根据这个关系从后向前遍历DP数组可以找出所有满足条件的数的路径. 再根据关系从前往后输出.  下面是代码: #include <stdio.

NVIDIA DIGITS 学习笔记(NVIDIA DIGITS-2.0 + Ubuntu 14.04 + CUDA 7.0 + cuDNN 7.0 + Caffe 0.13.0)

转自:http://blog.csdn.net/enjoyyl/article/details/47397505?from=timeline&isappinstalled=0#10006-weixin-1-52626-6b3bffd01fdde4900130bc5a2751b6d1 NVIDIA DIGITS-2.0 + Ubuntu 14.04 + CUDA 7.0 + cuDNN 7.0 + Caffe 0.13.0环境配置 引言 DIGITS简介 DIGITS特性 资源信息 说明 DIGI

Codeforces Round #277.5 (Div. 2)C. Given Length and Sum of Digits...(贪心)

传送门 Description You have a positive integer m and a non-negative integer s. Your task is to find the smallest and the largest of the numbers that have length m and sum of digits s. The required numbers should be non-negative integers written in the d

LeetCode 423. Reconstruct Original Digits from English——学会观察,贪心思路

Given a non-empty string containing an out-of-order English representation of digits 0-9, output the digits in ascending order. Note: Input contains only lowercase English letters. Input is guaranteed to be valid and can be transformed to its origina

LeetCode172 Factorial Trailing Zeroes. LeetCode258 Add Digits. LeetCode268 Missing Number

数学题 172. Factorial Trailing Zeroes Given an integer n, return the number of trailing zeroes in n!. Note: Your solution should be in logarithmic time complexity. (Easy) 分析:求n的阶乘中末位0的个数,也就是求n!中因数5的个数(2比5多),简单思路是遍历一遍,对于每个数,以此除以5求其因数5的个数,但会超时. 考虑到一个数n比他小

258. Add Digits

Given a non-negative integer num, repeatedly add all its digits until the result has only one digit. For example: Given num = 38, the process is like: 3 + 8 = 11, 1 + 1 = 2. Since 2 has only one digit, return it. Follow up:Could you do it without any

[leetcode] 258. Add Digits

Given a non-negative integer num, repeatedly add all its digits until the result has only one digit. For example: Given num = 38, the process is like: 3 + 8 = 11, 1 + 1 = 2. Since 2 has only one digit, return it. Follow up:Could you do it without any

Add Digits

题目: Given a non-negative integer num, repeatedly add all its digits until the result has only one digit. For example: Given num = 38, the process is like: 3 + 8 = 11, 1 + 1 = 2. Since 2 has only one digit, return it. Follow up:Could you do it without

[LeetCode] Add Digits

Given a non-negative integer num, repeatedly add all its digits until the result has only one digit. For example: Given num = 38, the process is like: 3 + 8 = 11, 1 + 1 = 2. Since 2 has only one digit, return it. 分析一:最简单的循环方法 class Solution { public: