Computer >> 컴퓨터 >  >> 프로그램 작성 >> C++

C++에서 여러 개의 유사한 숫자를 포함하는 n보다 작은 정수를 찾는 프로그램

<시간/>

정수 n이 있다고 가정하고 n보다 작거나 같은 양의 정수의 수를 찾아야 합니다. 여기서 정수는 최소한 두 번 이상 나타나는 숫자를 가집니다.

따라서 입력이 n =200과 같으면 출력은 38이 됩니다.

이 문제를 해결하기 위해 다음 단계를 따릅니다. −

  • 배열 정의 a

  • 초기화 x :=n의 경우 x가 0이 아닌 경우 x :=x / 10을 업데이트하고 -

    를 수행합니다.
    • 끝에 x mod 10 삽입
  • 배열 반전 a

  • 렛 :=n

  • w :=1, d :=1 초기화의 경우, w

    • d :=d * min(9, 10 - w + 1)

    • 렛 :=렛 - d

  • go() 함수를 정의합니다. 이것은 논쟁이 필요하지 않습니다.

    • b :=(1 비트 왼쪽 시프트 10) − 1

    • initialize i :=0의 경우, i

      • 초기화 d :=i <1의 경우, d

        • 렛 :=렛 − x

      • ((1 비트 왼쪽 시프트 a[i]) 비트 AND b)가 0이 아닌 경우

        • b :=b XOR (1 비트 왼쪽 시프트 a[i])

      • 그렇지 않으면

        • 반환

    • (ret 1 감소)

  • go()

    함수 호출
  • 리턴 렛

이해를 돕기 위해 다음 구현을 살펴보겠습니다. −

예시

#include <bits/stdc++.h>
using namespace std;
int solve(int n) {
   vector<int> a;
   for (int x = n; x; x /= 10) a.push_back(x % 10);
   reverse(a.begin(), a.end());
   int ret = n;
   for (int w = 1, d = 1; w < a.size(); ++w) {
      d *= min(9, 10 − w + 1);
      ret −= d;
   }
   auto go = [&]() {
      int b = (1 << 10) − 1;
      for (int i = 0; i < a.size(); ++i) {
         for (int d = (i < 1); d < a[i]; ++d) {
            int x = 0;
            if ((1 << d) & b) ++x;
               for (int j = i + 1; j < a.size(); ++j) x *= 10 − j;
               ret −= x;
            }
            if ((1 << a[i]) & b)
            b ^= (1 << a[i]);
            else
            return;
         }
         −−ret;
      };
      go();
      return ret;
}
int main(){
   cout << solve(200) << endl;
   return 0;
}

입력

200

출력

38