uva 10624 - Super Number

点击打开链接

题目意思:  给定n和m 现在要求找到一个m位数的树使得,对于m的前i位数都是i的倍数,n <= i <= m, 而且这个数的第一位数不能为0,如果找到就输出这个数,否则输出-1

解题思路:    1  目前只懂得用深搜回溯做,只是这一题的数据没有想象中的那么大,所以加上一些剪枝即可水过(数据强的话肯定TLE)
                      2  我们知道这个解空间树有m层,每一层的可能取值有10种(第一个除外),那么最大的m = 29 ,那么时间复杂都就是 10^29次方,这么大的时间你敢用吗。由于这一 题的数据比较水,那么可以过。但是由于最大的数值超过了int,我们必须用数组模拟。
                      3  思路: 从第一层开始搜索,注意第一层不能为0,我们用k(这里第一层k = 1)表示当前的层数。对于k < n时候我们不用考虑能否被k整除直接往下搜素,当k >= n 时候我们就要考虑当前的这个大数能否被k整除,如果可以就往下继续搜索,最后如果当k > m时候说明已经找到了,并且我们已经从0开始搜索,那么得到的答案就是最小值,这时候可以直接输出
                      4  注意事项:由于刚开始,我认为前i-1个位数是不用要求被当前的位数整除,并且认为第一个数就是1,然后就开了一段WA历程,后来找到了数据才发现尼玛坑爹啊哥哥我错了。第一位值不一定为1,所以我们必须从第一层开始向下搜索至m层,所以看到这个m这么大,你敢这么做吗

代码:

#include <algorithm>
#include <iostream>
#include <cstring>
#include <string>
#include <vector>
#include <cstdio>
#include <stack>
#include <queue>
#include <cmath>
using namespace std;

int t , n , m , flag;
int ans[50];

//判断当前数值能否被整除
int judge_divisible(int *tmp , int k){
    int d = 0;//d是于数
    for(int i = 1 ; i <= k ; i++){//从小到大来模拟除法运算
        d = d*10+tmp[i];
        d %= k;
    }
    return d;//直接返回说明有没有于数存在
}

//深搜(就去枚举每一个位数的情况)
void dfs(int Tans[] , int k){
    if(k > m) {
        memcpy(ans , Tans , sizeof(ans));
        flag = 1 ; return;
    }//如果当前的位数超过了m说明找到了这个标记flag为1
    for(int i = 0 ; i <= 9 ; i++){//枚举10个可能的值
        Tans[k] = i;//令这个位数的数值为i,就去判断能否符合
        if(Tans[1] != 0){
           if(k < n || k >= n && !judge_divisible(Tans , k))
              dfs(Tans , k+1);//继续深搜
           if(flag) return;//找到了就直接返回不再去搜索就是剪枝
        }
    }
}

//主函数
int main(){
    //freopen("input.txt" , "r" , stdin);
    int i , j;
    scanf("%d" , &t);
    for(i = 1 ; i <= t ; i++){
        scanf("%d%d" , &n , &m);
        memset(ans , 0 , sizeof(ans));
        flag = 0 ; dfs(ans , 1);
        printf("Case %d: " , i);
        if(flag){//如果当前有最小值输出这个值
            for(j = 1 ; j <= m ; j++) printf("%d" , ans[j]);
        }//没有的话输出-1
        else printf("-1");
        printf("\n");
    }
    return 0;
}
时间: 2024-07-29 09:30:00

uva 10624 - Super Number的相关文章

uva 10624 Super Number 回溯

  暴力回溯,用位运算加个奇偶剪枝   注意取余的效率,因为取余实在太慢了,所以要最少的进行取余运算,所以就是每19位进行次取余,这样1s内就过了 /* author:jxy lang:C/C++ university:China,Xidian University **If you need to reprint,please indicate the source** */ #include <stdio.h> int ans[50]; char nok(int now) { int i,

UVa 10624:Super Number, Rujia Liu的神题

链接: http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&category=112&page=show_problem&problem=1565 原题: Don't you think 162456723 very special? Look at the picture below if you are unable to find its speciality. (a | b mea

UVa 10013 Super long sums:简单高精度

10013 - Super long sums Time limit: 3.000 seconds http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&category=24&page=show_problem&problem=954 The Problem The creators of a new programming language D++ have found out that

UVa 10706:Number Sequence

链接: http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&category=113&page=show_problem&problem=1647 原题: A single positive integer i is given. Write a program to find the digit located in the position i in the sequence of n

uva 10591 - Happy Number hash

   非常简单的题,易知平方和后不超过800,开个800的数组,预处理,然后直接定址就可以了,不过要注意a和an的区别 /* author:jxy lang:C/C++ university:China,Xidian University **If you need to reprint,please indicate the source** */ #include <iostream> #include <cstdio> #include <cstdlib> #in

uva 10591 - Happy Number

点击打开链接 题目意思:  给定一个数n,然后进行操作,先求出这个数每一位的平方和,然后这个和替代n继续做这个操作,知道当前的n为1 或 n之前以经出现过 ,如果n等于则是happy number ,反之不是. 解题思路:  暴力搜素+状态判重.                      对于这一题一个状态就是这个数字n,由于最大的n是10^9,那么平方和最大不超过1000,我们开一个vis[1000]数组来做为标记数组即可,当遇到n 初始值 或 vis[n] = 1则退出,初始化vis[1]

UVa 10591:Happy Number

题目链接: http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&category=24&page=show_problem&problem=1532 类型: 哈希表 原题: Let the sum of the square of the digits of a positive integer S0 be represented by S1. In a similar way, let

泛型

 什么是Java泛型                1.java泛型是java SE 1.5的新特性,泛型的本质是参数化类型,也就是说所操作的数据类型被指定为一个参数.这种参数类型可以用在类.接口和方法的创建中,分别称为泛型类.泛型接口.泛型方法.                2.java泛型可以让你消除代码中的强制类型转换,同时获得一个附加的类型检查层,该检查层可以防止有人将错误类型的键或值保存在集合中.这就是泛型所做的工作. 为什么要有泛型 先来看看以下代码,        publi

Java千百问_05面向对象(008)_java中覆盖是什么

1.什么是覆盖 在Java中,覆盖是针对继承才有的概念,某一个子类需要某些方法或属性,但又不想使用父类中的同名的方法或属性,就需要使用覆盖.  直白的来说,就是在子类中编写与父类同名.同参数.同返回值的方法,或同名.同类型的属性,子类对象调用该方法/属性时,运行的是子类的方法,而不会执行父类的方法(除非在方法第一行写super();会先执行父类方法,再继续执行子类代码.) 了解类的构造函数看这里:类.对象到底有什么秘密  了解更多继承看这里:java类的继承有什么意义 2.构造函数如何覆盖 了解