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

2004 Asia Regional Shanghai

一个数论中的结论:对于任意的整数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;
    }
}
时间: 2024-11-08 23:24:08

hdu 1664(数论+同余搜索+记录路径)的相关文章

HDU 1160 FatMouse&#39;s Speed 动态规划 记录路径的最长上升子序列变形

题目大意:输入数据直到文件结束,每行两个数据 体重M 和 速度V,将其排列得到一个序列,要求为:体重越大 速度越低(相等则不符合条件).求这种序列最长的长度,并输出路径.答案不唯一,输出任意一种就好了. 题目思路:这是个最长上升子序列的问题,我们按W的升序进行排序,若W相等则按V的降序排序.用Pre[]记录当前点的前驱节点,Last记录序列最后一个点,maxn记录最长长度,完成动规后可根据Last和Pre[]输出路径. #include<cstdio> #include<stdio.h&

Pots POJ - 3414 (搜索+记录路径)

Pots Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 22688   Accepted: 9626   Special Judge Description You are given two pots, having the volume of A and B liters respectively. The following operations can be performed: FILL(i)        f

HDU 1503 Advanced Fruits(LCS+记录路径)

http://acm.hdu.edu.cn/showproblem.php?pid=1503 题意: 给出两个串,现在要确定一个尽量短的串,使得该串的子串包含了题目所给的两个串. 思路: 这道题目就是要我们求LCS,记录好路径就好. 1 #include<iostream> 2 #include<algorithm> 3 #include<cstring> 4 #include<cstdio> 5 #include<sstream> 6 #inc

hdu 5092 Seam Carving(DP+记录路径)

Seam Carving Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others) Total Submission(s): 119    Accepted Submission(s): 69 Problem Description Fish likes to take photo with his friends. Several days ago, he found that som

hdu 1258 Sum It Up (dfs+路径记录)

Sum It Up Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 3953    Accepted Submission(s): 2032 Problem Description Given a specified total t and a list of n integers, find all distinct sums usi

hdu 1226 BFS + bfs记录路径

http://acm.hdu.edu.cn/showproblem.php?pid=1226 为了省空间,可以用vis数组初始化的时候初始化为-1, 发现一个BFS容易错的地方 开始一直WA在这里:就是我int tp=q.front();之后马上q.pop():了,然后才去判断是不是符合条件以break,这样就不能根据q.empty()==1认为没有找到ans 因为这里WA了 其实也可以vis[0] == -1来判断 比较不理解的是 当n==0的时候 %n==0的时候怎么处理 //#pragma

FatMouse&#39;s Speed hdu 1160(动态规划,最长上升子序列+记录路径)

http://acm.hdu.edu.cn/showproblem.php?pid=1160 题意:现给出老鼠的体重与速度,要求你找出符合要求的最长子序列.       要求是 W[m[1]] < W[m[2]] < ... < W[m[n]](体重) && S[m[1]] > S[m[2]] > ... > S[m[n]] (速度) 分析:有两个变量的话比较不好控制,自然需要先排序.再仔细思考的话,觉得和之前做的防御导弹有点类似,都是求最多能有几个符合

HDU 1160 FatMouse&#39;s Speed (最长上升子序列+记录路径)

题目链接:HDU 1160 FatMouse's Speed 题意:求体重越重,反而速度越慢的例子,并输出对应的编号. 对speed进行从大到小排序,再求weight的最长上升序列,并输出路径. AC代码: #include<stdio.h> #include<algorithm> #include<stack> using namespace std; struct Node { int weight; int speed; int id; }; struct Nod

HDU 5137 How Many Maos Does the Guanxi Worth(floyd记录路径)

题意:给定N个点和M条边,点编号是1到N.现在要从2到N-1中选择一个删除,同时跟选择的点连接的边也就消失,然后使得点1到N的最短路径的长度最大.如果点1和点N不连通,则输出"Inf". 思路:直接暴力,枚举删去的点即可.我做了一步优化,只删原图最短路上的点, 所以用floyd的时候记录路径即可 //Accepted 1164 KB 0 ms #include<cstdio> #include<iostream> #include<cstring>