• 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;
        }
    }
  • 相关阅读:
    oracle系列--第五篇 PLSQL连接本地的Oracle数据库
    oracle系列--第四篇 Oracle的卸载
    oracle系列--第三篇 Oracle的安装
    oracle系列--第二篇 oracle下载
    WinForm多语言版本实战项目演练
    从C#垃圾回收(GC)机制中挖掘性能优化方案
    jvm内存模型和垃圾回收
    servlet匹配路径时/和/*的区别(转)
    十大经典排序算法(动图演示)(转)
    排序算法
  • 原文地址:https://www.cnblogs.com/liyinggang/p/5745819.html
Copyright © 2020-2023  润新知