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

ค้นหาจำนวนที่ผลรวมของ XOR กับช่วงอาร์เรย์ที่กำหนดสูงสุดโดยใช้ C++


เพื่อแก้ปัญหาที่เราได้รับอาร์เรย์และแบบสอบถามบางอย่าง ตอนนี้ในแต่ละแบบสอบถาม เราได้รับช่วง ตอนนี้เราต้องหาตัวเลขที่ทำให้ผลรวมของ xor กับ x ขยายใหญ่สุด ตัวอย่างเช่น

Input : A = {20, 11, 18, 2, 13}
Three queries as (L, R) pairs
1 3
3 5
2 4
Output : 2147483629
2147483645
2147483645

ในปัญหานี้ เราจะนับคำนำหน้าของ 1 ที่มีอยู่ในตัวเลขในแต่ละตำแหน่งในขณะนี้ เนื่องจากเราได้คำนวณจำนวนล่วงหน้าแล้ว ดังนั้น ในการหาจำนวนในช่วงที่กำหนดจาก L ถึง R เราจำเป็นต้อง ลบ สันนิษฐาน ถึง R โดย สันนิษฐาน ถึง L.

แนวทางในการหาแนวทางแก้ไข

ในแนวทางนี้ เนื่องจากเราต้องหาผลรวมสูงสุด เราจึงต้องทำให้บิตส่วนใหญ่ของ xor เท่ากับ 1 ดังนั้นเราจึงตรวจสอบว่าบิตใดมีค่ามากกว่า 0 หรือไม่ ดังนั้นเราจึงรีเซ็ตบิตของ x นั้น เนื่องจากตอนนี้ตัวเลขส่วนใหญ่มีบิตนั้นเท่ากับ 1 ดังนั้นเมื่อเราจับคู่ส่วนใหญ่ 1 กับ 0 ดังนั้นในที่สุดเราก็ได้เสียงส่วนใหญ่ บิตนั้นเท่ากับ 1 ดังนั้นเราจึงเพิ่มคำตอบให้สูงสุด

ตัวอย่าง

รหัส C++ สำหรับแนวทางข้างต้น

#include <bits/stdc++.h>
using namespace std;
#define MAX 2147483647 // 2^31 - 1
int prefix[100001][32]; // the prefix array
void prefix_bit(int A[], int n){ // taking prefix count of 1's present
    for (int j = 0; j < 32; j++) // we keep 0th count as 0 and our prefix array starts with index 1
        prefix[0][j] = 0;
    for (int i = 1; i <= n; i++){ // making our prefix array
        int a = A[i - 1]; // ith element
        for (int j = 0; j < 32; j++){ // as our number is less than 2^32 so we traverse for bit 0 to 31
            int x = 1 << j; // traversing in bits
            if (a & x) // if this bit is one so we make the prefix count as prevcount + 1
                prefix[i][j] = 1 + prefix[i - 1][j];
            else
                prefix[i][j] = prefix[i - 1][j];
       }
   }
}
int maximum_num(int l, int r){
    int numberofbits = r - l + 1; // the number of elements in the range hence the number of bits
    int X = MAX; // we take the max value such that all of it's bits are one
    // Iterating over each bit
    for (int i = 0; i < 31; i++){
        int x = prefix[r][i] - prefix[l - 1][i]; // calculating the number of set bits in the given range
        if (x >= numberofbits - x){ // is number of 1's is more than number of 0's
            int currentbit = 1 << i; // we set the current bit to prefix for toggling that bit in x
            X = X ^ currentbit; // we make toggle that bit from 1 to 0
        }
    }
    return X; // answer
}
int main(){
    int n = 5, q = 3; // number of element in our array and number of queries present
    int A[] = { 210, 11, 48, 22, 133 }; // elements in our array
    int L[] = { 1, 4, 2 }, R[] = { 3, 14, 4 }; // given queries
    prefix_bit(A, n); // creating prefix bit array
    for (int i = 0; i < q; i++)
       cout << maximum_num(L[i], R[i]) << "\n";
    return 0;
}

ผลลัพธ์

2147483629
2147483647
2147483629

คำอธิบายของโค้ดด้านบน

ในแนวทางนี้ ก่อนอื่นเราจะคำนวณจำนวนคำนำหน้าของ 1 ปัจจุบันสำหรับแต่ละบิต ตอนนี้เมื่อเราได้จำนวนนี้แล้ว เราก็ได้แก้ปัญหาที่ใหญ่ที่สุดของเราซึ่งก็คือการข้ามผ่านข้อความค้นหา ณ ตอนนี้ เราจะไม่ข้ามผ่านแต่ละช่วง ดังนั้นเราสามารถคำนวณมันผ่านอาร์เรย์คำนำหน้าของเราได้แล้ว ตรรกะหลักของเราคือ เราคำนวณจำนวนการรีเซ็ตและการตั้งค่าบิตในช่วงเมื่อเราพบตำแหน่งที่หมายเลขบิตที่ตั้งไว้มากกว่าจำนวนบิตรีเซ็ต ดังนั้นเราจึงรีเซ็ตบิตนั้นใน x ของเราทันทีเมื่อเราเริ่มต้น x ด้วย 2^31 - 1 ดังนั้นบิตทั้งหมดจะถูกตั้งค่า และเราพบคำตอบของเราโดยสลับบิตใน x

บทสรุป

ในบทช่วยสอนนี้ เราแก้ปัญหาเพื่อค้นหาจำนวนที่ผลรวมของ XOR กับช่วงอาร์เรย์ที่กำหนดเป็นค่าสูงสุด นอกจากนี้เรายังได้เรียนรู้โปรแกรม C++ สำหรับปัญหานี้และแนวทางที่สมบูรณ์ (ปกติ) ซึ่งเราแก้ไขปัญหานี้ เราสามารถเขียนโปรแกรมเดียวกันในภาษาอื่นๆ เช่น C, java, python และภาษาอื่นๆ เราหวังว่าคุณจะพบว่าบทช่วยสอนนี้มีประโยชน์