2012-09-22 12 views
6

दिए गए एन पूर्णांक और एक पूर्णांक के, यह बताएं कि दिए गए एन पूर्णांक के कितने जोड़े मौजूद हैं कि जोड़ी में दो तत्वों का योग के द्वारा विभाजित किया जा सकता है?इष्टतम एल्गोरिदम को किसी दिए गए पूर्णांक के द्वारा विभाजित जोड़े खोजने के लिए आवश्यक

मुझे एन और के पर सीमाएं नहीं पता हैं। तो, सादगी के लिए, मान लें कि एन और के बहुत बड़े नहीं हैं।

यह कहने के बिना चला जाता है, यथासंभव इष्टतम समाधान के रूप में दें। (मुझे मूर्ख विधि पता है :-)!)

उत्तर

21

चाहे k द्वारा दो संख्याओं का योग विभाजित हो, केवल उनके रहने वाले मॉड्यूल k पर निर्भर करता है।

तो k उचित रूप से छोटा है, तो आप केवल यह अनुमान लगा सकते हैं कि प्रत्येक संभव शेष कितनी संख्या है और उससे जोड़े की संख्या की गणना करें। k > 0 मान लिया जाये और सभी पूर्णांकों गैर नकारात्मक

unsigned long long combinations(unsigned k, unsigned long long *arr, unsigned n) { 
    unsigned long long counts[k] = {0}; 
    unsigned i; 
    for(i = 0; i < n; ++i) { 
     ++counts[arr[i]%k]; 
    } 
    // number of pairs where both are divisible by k 
    unsigned long long combs = counts[0]*(counts[0]-1)/2; 
    for(i = 1; i < (k+1)/2; ++i) { 
     combs += counts[i]*counts[k-i]; 
    } 
    if (k == 2*i) { 
     combs += counts[i]*(counts[i] - 1)/2; 
    } 
    return combs; 
} 

O(n+k) चरणों में काम करता है। यदि n छोटा है और k बहुत बड़ा है, तो बेवकूफ एल्गोरिदम बेहतर है।

+0

आपने मुझे इसे हराया :) हालांकि, आप गणना [], arr नहीं [] जहां आप कॉम्ब्स कर रहे हैं, का उपयोग करना चाहते हैं, और आपको गणना [0] – rici

+0

ग्रेट पर विचार करने की आवश्यकता है! रैखिक समय .. यही वह है जो मैं ढूंढ रहा था .. धन्यवाद! – user1599964

+0

@rici हेड-अप के लिए धन्यवाद। 'counts [0]' 'combs' के प्रारंभ में उपयोग किया जाता है, मुझे यह नहीं भूल गया था (लेकिन मेरे पास' k-i' के बजाय एक और टाइपो, 'k-1' था)। –

3

डैनियल फिशर के अलावा, यदि के बहुत बड़ा है, तो आप संख्याओं को छोटा कर सकते हैं, और फिर दोनों सिरों से क्रमबद्ध सूची (0 मोड के मानों से निपटने के बाद) मध्य (के/2 मॉड के)। वह ओ (एन लॉग एन) है, जो ओ (एन^2) बेहतर है, यह मानते हुए कि आपका बेवकूफ एल्गोरिदम वास्तव में बेवकूफ है।

+0

माई बेव में बाइनरी सर्च शामिल है ... तो यह भी ओ (एन लॉग एन) होगा, लेकिन हाँ, आपका संस्करण एक सुधार है ... क्योंकि इसमें केवल सॉर्टिंग के लिए ओ (एन लॉग एन) शामिल है .. और रैखिक में ढूंढता है ओ (एन) बाइनरी खोज का उपयोग कर ओ (एन लॉग एन) के बजाय समय। धन्यवाद ! +1 :) – user1599964

+0

ओ (एन) पर जाने के लिए आप सॉर्टिंग/बाइनरी खोज के बजाय हैशटेबल का उपयोग कर सकते हैं। –

+0

@ किथरंडल, हाँ, आप इसे आजमा सकते हैं। मैं उम्मीद करता हूं कि मेरा समाधान आमतौर पर तेज़ होगा, क्योंकि इसका आंतरिक पाश बहुत तेज़ है, लेकिन मैं गलत भी हो सकता था। यदि आप इसे आजमा देना चाहते हैं, तो मैं सुझाव दूंगा कि एक पूर्णांक हैश के लिए एक अच्छा हैश पूर्णांक mod ​​k mod p होगा जहां पी n के निकट एक प्रमुख है। यह स्टोरेज को ओ (एन) में रखता है, जो खोज-और-स्कैन के साथ प्रतिस्पर्धी है। (पूर्णांक मोड के स्वयं का उपयोग करना निश्चित रूप से कोई टकराव की गारंटी नहीं देगा, लेकिन फिर आपने समस्या को डैनियल के बिन्सोर्ट में कम कर दिया है, और हमने इस मामले में त्याग दिया है क्योंकि डिब्बे बहुत अधिक मेमोरी लेते हैं।) – rici

संबंधित मुद्दे