2015-10-02 14 views
5

Original Problem: Problem 2सबसे बड़ा खाली आयत जिसका आधार x- अक्ष

पर एक आयताकार स्थान जिसकी ऊंचाई 500 है और चौड़ाई 10^5 है, तो हम एन अंक दिया जाता है।

हमें सबसे बड़ा उप-आयताकार पता होना चाहिए जिसका आधार एक्स-अक्ष पर है और इसमें उचित बिंदुओं में से कोई भी बिंदु नहीं है (लेकिन उन्हें अपने किनारों में शामिल किया जा सकता है)।

#include <iostream> 
#include <algorithm> 

const int nWidth = 100000; 
const int nHeight = 500; 

int main(){ 

    int *nMaxHeights = new int[nWidth]; 
    std::fill (nMaxHeights, nMaxHeights+nWidth, nHeight); 

    int N; 
    std::cin >> N; 
    for (int x,y,iii=0; iii < N; iii++){ 
    std::cin >> x >> y; 
    nMaxHeights[x] = std::min(y+1, nMaxHeights[x]); 
    } 

    int maxArea = 0; 
    for (int jjj,iii=0; iii < nWidth; iii++){ 
    for (jjj=iii; jjj < nWidth; jjj++){ 
     if (nMaxHeights[jjj] < nMaxHeights[iii]) 
     break; 
    } 
    maxArea = std::max((jjj-iii+1)*nMaxHeights[iii],maxArea); 
    } 

    std::cout << maxArea; 

    return 0; 
} 

यह काम करता है, फिर भी स्पष्ट रूप से एक टीएलई (निष्पादन समय सीमा पार हो गई) प्राप्त करता है:

मैं एक हे (चौड़ाई^2) कलन विधि की कोशिश की।

मैं बेहतर कैसे कर सकता हूं?

उत्तर

0

दिलचस्प समस्या। इन्हें इंगित करने के लिए धन्यवाद।

मैंने एक एल्गोरिदम का उपयोग किया, जो बड़े N (अंक की संख्या) और अंक के यादृच्छिक वितरण के लिए O(N) स्केल करता है। इसके पीछे विचार: प्रत्येक आयताकार कुछ बिंदुओं से घिरा होगा।

  1. यदि एक एक्स मान के लिए अधिक अंक हैं, तो केवल निम्नतम मूल्य वाले एक का उपयोग किया जाता है।
  2. पहले चरम एक्स अंक की जांच करें; सबसे सही और सबसे बाएं, एक आयताकार को रेत में फैला रहा है। सीमा।
  3. फिर सही बिंदु पर जाएं और इसमें एक आयताकार बनाने का प्रयास करें। दो संभावनाएं हैं:
    1. यह बिंदु एक क्षैतिज किनारे पर है: अपने दो पड़ोसी, बाएं और दाएं को ढूंढें, जिनके पास कम वाई मान है, और बाएं resp resp resp resp resps के बिंदुओं के रूप में उनका उपयोग करें। दायां किनारा यदि कोई बाएं/दाएं पड़ोसी नहीं है, तो अंतरिक्ष के अंत का उपयोग करें।
    2. यह बिंदु लंबवत किनारे पर है: अगली-बाएं बिंदु खोजें, क्षैतिज किनारे के रूप में अंतरिक्ष की (y-) सीमा का उपयोग करें।
  4. प्रत्येक बिंदु के लिए, संभावित आयताकार क्षेत्रों (उपरोक्त दो संभावनाएं) की गणना करें, और यदि कोई भी वर्तमान सबसे बड़ा क्षेत्र से बड़ा है, तो सबसे बड़ा क्षेत्र अपडेट करें।

यहाँ अजगर, http://pastebin.com/068ByYwh में कुछ नमूना कार्यान्वयन है, लेकिन मैं सकारात्मक नहीं हूँ, कि यह शामिल नहीं है कीड़े ;-)

0

केवल एक अंक की कल्पना करें। तीन संभावित आयताकार हैं: बिंदु के नीचे, इसके बाईं ओर और इसके दाईं ओर।

मान लें कि अब दो बिंदु हैं। आइए पहले नीचे के करीब एक को देखें। फिर, इस चरण में तीन मामले हैं। इस बिंदु के नीचे एक आयताकार है। दूसरी तरफ के विपरीत तरफ एक आयताकार भी है। और दूसरी तरफ पक्ष है, जहां अधिक आयताकार हैं।

आईओओ, यदि आप नीचे के बिंदुओं को देखते हैं, तो प्रत्येक बिंदु के नीचे एक आयताकार होता है और यह बिंदु अंतरिक्ष को दो लंबवत बैंड में विभाजित करता है, जिनमें से प्रत्येक में अन्य बिंदु होते हैं, जो समान रूप से आयताकार होते हैं और आगे कौन सा अंतरिक्ष subdivide।

तो, वाई और एक्स दोनों द्वारा अंक को क्रमबद्ध करना उचित लगेगा (शायद, उन्हें दो क्रमबद्ध पेड़ों के नोड्स बनाकर, वाई द्वारा क्रमबद्ध एक (ताकि आप वाई में आगे बढ़ सकें) और दूसरा एक्स द्वारा क्रमबद्ध किया जा सके। (इसलिए आप बाएं/दाएं स्थानांतरित/खोज सकते हैं)), जो एन * लॉग (एन) है, और उसके बाद रिक्त रूप से सभी बिंदुओं पर जाएं, उचित रूप से स्पेस को विभाजित करना, जो एक और एन * लॉग (एन) जैसा दिखता है।

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