Problem p02720 (C++) — buggy submission, verdict: Time Limit Exceeded

#include <iostream>
using namespace std;

void lunlun_init(long long &num, int &count, int k);
int lunlun(long long &num, int &count, int k, int pos, int upper);

int getDigit(long long num, int i);

int getUppestPos(long long num);

int getUppestDigit(long long num);

long long pow10(int n);
void alterDigit(long long &num, int pos, int oldDigit, int newDigit);

int main() {
  long long num = 1;
  int count = 0;
  int k;
  cin >> k;

  lunlun_init(num, count, k);

  cout << num;
  return 0;
}

// needs recusion , when the recursion reach the lowest digit ,it will set as
// the adjacent upper digit's lunlun digit needs init call,  the uppest digit
// will add 1 when the lunlun func has return. when the uppest digit is already
// 9, then it will add to its upper digit
void lunlun_init(long long &num, int &count, int k) {
  int uppestPos = getUppestPos(num);
  int uppestDigit = getUppestDigit(num);
  while (count < k) {
    // loop the uppest

    if (lunlun(num, count, k, uppestPos - 1, uppestDigit))
      return;
    num += pow10(uppestPos);
    if (uppestDigit == 9) {
      uppestDigit = 1;
      uppestPos++;
    } else
      uppestDigit++;
  }
}

// only when the recursion reach the lowest , the count will add
int lunlun(long long &num, int &count, int k, int pos, int upper) {
  if (pos < 0) {
    count++;
    if (count == k)
      return 1;
    return 0;
  }
  if (pos == 0) {
    int digit = 0;
    // three cases
    digit = getDigit(num, pos);
    // case 1
    if (upper - 1 >= 0) {
      alterDigit(num, pos, digit, upper - 1);
      // count
      count++;
      // judge
      if (count == k)
        return 1;
    }
    // case2
    digit = getDigit(num, pos);
    alterDigit(num, pos, digit, upper);
    count++;
    if (count == k)
      return 1;
    // case3
    if (upper + 1 <= 9) {
      digit = getDigit(num, pos);
      alterDigit(num, pos, digit, upper + 1);
      // count
      count++;
      // judge
      if (count == k)
        return 1;
    }
    return 0;
  }

  // three cases
  int digit = 0;
  // three cases
  digit = getDigit(num, pos);
  // case 1
  if (upper - 1 >= 0) {
    alterDigit(num, pos, digit, upper - 1);
    if (lunlun(num, count, k, pos - 1, upper - 1))
      return 1;
  }
  // case2
  digit = getDigit(num, pos);
  alterDigit(num, pos, digit, upper);
  if (lunlun(num, count, k, pos - 1, upper))
    return 1;
  // case3
  if (upper + 1 <= 9) {
    digit = getDigit(num, pos);
    alterDigit(num, pos, digit, upper + 1);
    if (lunlun(num, count, k, pos - 1, upper + 1))
      return 1;
  }
  return 0;
}

// int lunlunAdjacent(long long num,int i){
//	//has upper digit (no need to judge)
//  // if(num >=  pow10(i+1)){
//   //    if(!lunlunDigit(getDigit(num,i+1),getDigit(num,i)))
//    //     return 0;
//   //  }
//   //has lower digit
//   if(i-1 >=0){
//     if(!lunlunDigit(getDigit(num,i-1),getDigit(num,i)))
//       return 0;
//   }
//   return 1;
// }

int getDigit(long long num, int i) { // start from 0
  num = (num % pow10(i + 1)) / pow10(i);
  return (int)num;
}

int getUppestPos(long long num) {

  int i = 0;
  while (num > 0) {
    num /= 10;
    i++;
  }
  return --i;
}

int getUppestDigit(long long num) {
  while (num / 10 > 0)
    num /= 10;
  return (int)num;
}

long long pow10(int n) { // 10^n
  if (n == 0)
    return 1;
  return pow10(n - 1) * 10;
}

void alterDigit(long long &num, int pos, int oldDigit, int newDigit) {
  num -= oldDigit * pow10(pos);
  num += newDigit * pow10(pos);
}

Error: TLE

Fixed submission:

#include <iostream>
using namespace std;

int lunlun(long long num);

int lunlunAdjacent(long long num, int i);

int getDigit(long long num, int i);

long long pow10(int n);

int lunlunDigit(int dg1, int dg2);

int main() {
  int k;
  cin >> k;
  long long num = 0;
  for (int i = 0; i < k;) {
    if (lunlun(++num))
      i++;
  }
  cout << num;
  return 0;
}

int lunlun(long long num) {
  for (int i = 0; num >= pow10(i); i++) { // position i has digit
    if (!lunlunAdjacent(num, i))
      return 0;
  }
  return 1;
}

int lunlunAdjacent(long long num, int i) {
  // has upper digit (no need to judge)
  // if(num >=  pow10(i+1)){
  //    if(!lunlunDigit(getDigit(num,i+1),getDigit(num,i)))
  //     return 0;
  //  }
  // has lower digit
  if (i - 1 >= 0) {
    if (!lunlunDigit(getDigit(num, i - 1), getDigit(num, i)))
      return 0;
  }
  return 1;
}

int getDigit(long long num, int i) { // start from 0
  num = (num % pow10(i + 1)) / pow10(i);
  return (int)num;
}

long long pow10(int n) { // 10^n
  if (n == 0)
    return 1;
  return pow10(n - 1) * 10;
}

int lunlunDigit(int dg1, int dg2) {
  int diff = dg1 - dg2;
  if (diff <= 1 && diff >= -1)
    return 1;
  else
    return 0;
}