• 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 AWR 和 ASH
    11g RAC R2 日常巡检--Grid
    Linux中重命名文件
    Xshell4连接Linux后 win快捷键锁屏
    vim 删除临时文件
    shell--read命令
    shell基础篇(一)从hello world开始
    ORACLE--分区表数据清理
    Shell—学习之心得
    awk 手册--【转载】
  • 原文地址:https://www.cnblogs.com/liyinggang/p/5745819.html
Copyright © 2020-2023  润新知