hihoCoder #1558 : H国的身份证号码I

题目:

描述
H国的身份证号码是一个N位的正整数(首位不能是0)。此外,由于防伪需要,一个N位正整数是合法的身份证号码当且仅当每位数字都小于等于K,并且任意相邻两位数字的乘积也小于等于K。

例如对于K=5, 101、211、210等都是合法的号码,而106、123、421等都是非法的号码。

给定一个正整数N以及K,请从小到大输出所有合法的号码。

输入 两个整数N和K。

对于80%的数据,1 ≤ N ≤ 6。

对于100%的数据,1 ≤ N ≤ 9,1 ≤ K ≤ 5。

输出 按从小到大的顺序输出所有合法的N位号码,每个号码占一行。

样例输入

2 4

样例输出

10
11
12
13
14
20
21
22
30
31
40
41

原题链接:https://hihocoder.com/problemset/problem/1558

很显然,这是一道水题,但是如果不优化一下的话会TLE的~

一开始的写法,也就是没优化之前如下,能通过90%,还有一个超时了:

#include<stdio.h>
#include<string.h>
#include<iostream>
#include<math.h>
using namespace std;
void isValid(int a,int n,int k){
    int xx[10] = {0};
    int t = n;
    int p = a;
    if(n == 1){
        if(a <= k){
            cout<<a<<endl;
        }
        return;
    }
    for(int i=0;i<n;i++){
        xx[i] = p%10;
        p /= 10;
        if(xx[i] > k){
            return;
        }
    }
    xx[n] = xx[0];
    for(int i=0;i<n-1;i++){
        if(xx[i] * xx[i+1] > k){
            return;
        }
    }
    cout<<a<<endl;
}
int main(){
  int n,k;
  while(cin>>n>>k){
    int minNum = pow(10,n-1);
    int maxNum = pow(10,n-1)*(k+1)+0.5;
    for(int i=minNum;i<maxNum;i++){
        isValid(i,n,k);
    }
  }
  return 0;
}

经过优化的代码如下,这个倒是AC了,优化思路也比较简单,比如k为5,那么当遍历到161的时候自动跳转到200,这样就省去很多次计算了:

#include<stdio.h>
#include<string.h>
#include<iostream>
#include<math.h>
using namespace std;
int main(){
  int n,k;
  while(cin>>n>>k){
    int minNum = pow(10,n-1)+0.5;

    int maxNum_1 = ((int)(pow(10,n-1)+0.5))*(k+1);
    int maxNum_2 = pow(10,n)+0.5;
    int maxNum = maxNum_1<maxNum_2?maxNum_1:maxNum_2;

    for(int i=minNum;i<maxNum;i++){

        int xx[10] = {0};
        int t = n;
        int p = i;
        bool flag = false;
        if(n == 1){
            if(i <= k){
                cout<<i<<endl;
            }
            continue;
        }
        for(int j=0;j<n;j++){
            xx[j] = p%10;
            p /= 10;
            if(xx[j] > k){
                if(j != 0){
                    int ttt = pow(10,1+j)+0.5;
                    i = ((i/ttt) * ttt+ttt);
                    i--;
                }
                flag = true;
                break;
            }
        }

        if(flag){
            flag = false;
            continue;
        }

        xx[n] = xx[0];
        for(int j=0;j<n-1;j++){
            if(xx[j] * xx[j+1] > k){
                flag = true;
                break;
            }
        }
        if(flag){
            flag = false;
            continue;
        }
        cout<<i<<endl;
    }
  }
  return 0;
}
posted @ 2017-08-20 16:16  _吟游诗人  阅读(148)  评论(0编辑  收藏  举报