hdu 1664(数论+同余搜索+记录路径)

Different Digits

Time Limit: 10000/4000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 1430    Accepted Submission(s): 392


Problem Description
Given a positive integer n, your task is to find a positive integer m, which is a multiple of n, and that m contains the least number of different digits when represented in decimal. For example, number 1334 contains three different digits 1, 3 and 4.
 
Input
The input consists of no more than 50 test cases. Each test case has only one line, which contains a positive integer n ( 1<=n < 65536). There are no blank lines between cases. A line with a single `0' terminates the input.
 
Output
For each test case, you should output one line, which contains m. If there are several possible results, you should output the smallest one. Do not output blank lines between cases.
 
Sample Input
7 15 16 101 0
 
Sample Output
7 555 16 1111
 
Source
 

一个数论中的结论:对于任意的整数n,必然存在一个由不多于两个的数来组成的一个倍数。因为a,aa,aaa……取n+1个,则必有两个模n余数相同,相减即得n的倍数m。而m只由a、0组成。

有了上述结论+同余剪枝,这个题就能够做出来了,还有这题需要手动记录路径,不能让string 在结构体里面,不然TLE,记录路径的话,由于实在是找不到独一无二的标志,所以将每个节点作为独一无二的标志,手动模拟队列记录。

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <queue>
#include <string>
using namespace std;
#define N 65536
typedef long long LL;
int n;
bool mod[N];
struct Node{
    int val,step,mod,pre;
}q[N];
int a[5];
int bfs(int k){
    memset(mod,0,sizeof(mod));
    int head = 0,tail = -1;
    for(int i=1;i<=k;i++){
        if(a[i]!=0){
            Node s;
            s.val = a[i],s.step = 0;
            s.pre = -1,s.mod = a[i]%n;
            mod[s.mod] = true;
            q[++tail] = s;
        }
    }
    while(head<=tail){
        Node now = q[head];
        if(now.mod==0){
            return head;
        }
        for(int i=1;i<=k;i++){
            Node next;
            next.mod = (now.mod*10+a[i])%n;
            next.pre = head;
            next.val = a[i];
            next.step = now.step+1;
            if(!mod[next.mod]){
                mod[next.mod] = true;
                q[++tail] = next;
            }
        }
        head++;
    }
    return -1;
}
string ans,res;
void getans(int k){
    if(k==-1) return ;
    getans(q[k].pre);
    ans+=(q[k].val+'0');
}
int main(){
    while(scanf("%d",&n)!=EOF,n){
        res = "";
        for(int i=1;i<=9;i++){
            a[1] = i;
            int f = bfs(1);
            if(f!=-1){
                ans = "";
                getans(f);
                if(res.compare("")==0) res = ans;
                else if(res.length()>ans.length()) res = ans;
            }
        }
        if(res.compare("")!=0){
            cout<<res<<endl;
            continue;
        }
        for(int i=0;i<=9;i++){
            a[1] = i;
            for(int j=i+1;j<=9;j++){
                a[2] = j;
                int f = bfs(2);
                if(f!=-1){
                    ans = "";
                    getans(f);
                    if(res.compare("")==0) res = ans;
                    else if(res.length()>ans.length()||res.length()==ans.length()&&ans.compare(res)<0) res = ans;
                }
            }
        }
        cout<<res<<endl;
    }
}
原文地址:https://www.cnblogs.com/liyinggang/p/5745819.html