Computer >> คอมพิวเตอร์ >  >> การเขียนโปรแกรม >> C++

โปรแกรมหาจำนวนเต็มน้อยกว่า n ที่มีตัวเลขใกล้เคียงกันหลายตัวใน C++


สมมติว่าเรามีจำนวนเต็ม n เราต้องหาจำนวนเต็มบวกที่น้อยกว่าหรือเท่ากับ n โดยที่จำนวนเต็มอย่างน้อยมีหลักเกิดขึ้นมากกว่าหนึ่งครั้ง

ดังนั้นหากอินพุตเท่ากับ n =200 เอาต์พุตจะเป็น 38

เพื่อแก้ปัญหานี้ เราจะทำตามขั้นตอนเหล่านี้ -

  • กำหนดอาร์เรย์

  • สำหรับการเริ่มต้น x :=n เมื่อ x ไม่ใช่ศูนย์ ให้อัปเดต x :=x / 10 ทำ -

    • แทรก x mod 10 ที่ส่วนท้ายของ a

  • กลับอาร์เรย์ a

  • ret :=n

  • สำหรับการเริ่มต้น w :=1, d :=1 เมื่อ w <ขนาดของ a อัปเดต (เพิ่ม w ขึ้น 1) ทำ -

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

    • ret :=ret − d

  • กำหนดฟังก์ชัน go() นี้ไม่มีอาร์กิวเมนต์

    • b :=(1 กะบิตซ้าย 10) − 1

    • สำหรับการเริ่มต้น i :=0, เมื่อ i

      • สำหรับการเริ่มต้น d :=i <1 เมื่อ d

        • ret :=ret − x

      • ถ้า ((1 กะซ้ายระดับบิต a[i]) ระดับบิต AND b) ไม่ใช่ศูนย์ ดังนั้น

        • b :=b XOR (1 bitwise shift ซ้าย a[i])

      • มิฉะนั้น

        • กลับ

    • (ลดหย่อน 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