क्या अब आप मुझे सुन सकते है?


23

पृष्ठभूमि

आप एक सॉफ्टवेयर साम्राज्य के एक अमीर कार्यकारी हैं। आपका समय बहुत पैसे के लायक है। जैसे, आपको हमेशा सबसे कुशल मार्ग में यात्रा करनी चाहिए। हालांकि, एक कार्यकारी के रूप में, आप महत्वपूर्ण फोन कॉल में भाग लेने में बहुत समय बिताते हैं। यह सर्वोपरि है कि आप कभी भी कॉल ड्रॉप नहीं करते हैं, इसलिए आपको उन क्षेत्रों के माध्यम से यात्रा नहीं करनी चाहिए जिनके पास सेल सेवा नहीं है!

चुनौती

आपको तीन-टुपल्स की सूची दी जाएगी, जिनमें से प्रत्येक सेल टॉवर के स्थान और शक्ति का प्रतिनिधित्व करता है। एक उदाहरण के रूप में, त्रिज्या 16 के एक सर्कल के साथ [50, 25, 16]स्थित एक सेल टॉवर का प्रतिनिधित्व करेगा जो <x,y> = <50, 25>इसके प्रभाव के सर्कल का प्रतिनिधित्व करता है। इस सूची को ध्यान में रखते हुए, आपको सेल सर्विस को खोए बिना कम से कम दूरी पर अपनी प्रारंभिक स्थिति से <0, 0>अपने गंतव्य पर यात्रा करनी चाहिए <511, 511>। यह , इसलिए सबसे छोटा कोड जीतता है!

इनपुट आउटपुट

आप इनपुट को एक ऐसे रूप में हेरफेर करने के लिए स्वतंत्र हैं जो पढ़ने में आसान बनाता है, जैसे कि फ़ाइल में, या STDIN के माध्यम से नेस्टेड सरणी के रूप में eval, आदि। आप इनपुट को हार्डकोड कर सकते हैं, इसलिए जब तक आपका कोड अन्य इनपुट के लिए काम करता है, तब तक कुंआ। इनपुट को हार्डकोड करने के लिए उपयोग किए जाने वाले सटीक वर्णों की गणना नहीं की जाएगी, लेकिन चर नाम और असाइनमेंट वर्ण होंगे। आपको यह नहीं मानना ​​चाहिए कि इनपुट किसी विशिष्ट क्रम में है, या यह कि प्रत्येक सेल टॉवर समस्या के लिए प्रासंगिक है। यदि आपके कोई प्रश्न हैं, तो कृपया एक टिप्पणी छोड़ दें और मैं इसे स्पष्ट करने का प्रयास करूंगा।

आउटपुट निर्देशांक की एक सूची होना है, अंक को इंगित करता है जब क्रम में जुड़ा हुआ है जो निकास के लिए एक रास्ता बनाता है। सटीकता की आवश्यकता केवल निकटतम पूर्णांक तक होनी चाहिए, और यदि आप मेरे आउटपुट उदाहरण में 1-2 यूनिट हैं, तो यह ठीक है। मैंने इसे स्पष्ट करने के लिए नीचे चित्र शामिल किए हैं।

शुभकामनाएँ!

उदाहरण

input:
[ 32,  42,  64]
[112,  99,  59]
[141, 171,  34]
[157, 191,  28]
[177, 187,  35]
[244, 168,  57]
[289, 119,  20]
[299, 112,  27]
[354,  59,  58]
[402,  98,  23]
[429,  96,  29]
[424, 145,  34]
[435, 146,  20]
[455, 204,  57]
[430, 283,  37]
[432, 306,  48]
[445, 349,  52]
[424, 409,  59]
[507, 468,  64]

टॉवर स्थान

output:
0 0
154 139
169 152
189 153
325 110
381 110
400 120
511 511

इष्टतम पथ

input2
[ 32,  42,  64]
[112,  99,  59]
[141, 171,  34]
[157, 191,  28]
[177, 187,  35]
[244, 168,  57]
[289, 119,  20]
[299, 112,  27]
[354,  59,  58]
[402,  98,  23]
[429,  96,  29]
[424, 145,  34]
[435, 146,  20]
[455, 204,  57]
[430, 283,  37]
[432, 306,  48]
[445, 349,  52]
[424, 409,  59]
[507, 468,  64]
[180, 230,  39]
[162, 231,  39]
[157, 281,  23]
[189, 301,  53]
[216, 308,  27]
[213, 317,  35]
[219, 362,  61]
[242, 365,  42]
[288, 374,  64]
[314, 390,  53]
[378, 377,  30]
[393, 386,  34]

उदाहरण 2

output2:
0 0
247 308
511 511

पिछले पथ को नीले रंग में हाइलाइट किया गया है, लेकिन आप देख सकते हैं कि अधिक टावरों के अलावा एक अधिक इष्टतम मार्ग की अनुमति देता है।

समाधान


2
क्या खत्म मान 511,511 है?
मिकी

2
इंटरमीडिएट के अंक कितने सही होंगे? वे पूर्णांक होना चाहिए?
कीथ रान्डेल

6
अगर मैं वास्तव में बहुत अमीर था, तो मैं (127, 127) त्रिज्या 182 में थोड़ी सुरंग के साथ एक टॉवर का निर्माण करूंगा।
एंटी अर्थ

1
सुसंगत नहीं: गंतव्य २५५,२५५ या ५११,५११ है?
edc65

2
मुझे लगता है कि कुछ तैयारी के बाद इस समस्या को इस चुनौती से कम करना संभव है । आप एक उदाहरण जोड़ना चाह सकते हैं जिसमें टावरों के कई रास्ते हैं।
मार्टिन एंडर

जवाबों:


18

अजगर, 1,291 1,271 1,225 बाइट्स

जैसा कि मार्टिन ने कहा, यह समस्या काफी हद तक उनकी उत्कृष्ट रबर बैंड चुनौती को कम कर सकती है । उस चुनौती की शब्दावली का उपयोग करते हुए, हम नाखून के दूसरे सेट के रूप में एन्कोडिंग क्षेत्र की सीमा पर हलकों के बीच चौराहे के बिंदुओं को ले सकते हैं :

आकृति 1

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

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

हम अपने पथों का निर्माण मूल रूप से मंडलियों के ग्राफ पर गहराई से पहली खोज करके करते हैं। हम खोज के प्रत्येक चरण में संभावित खोज निर्देशों को समाप्त करने का एक तरीका खोज रहे हैं।

मान लीजिए कि किसी बिंदु पर हम एक वृत्त A पर हैं , जिसके दो समीपवर्ती वृत्त B और C हैं , जो एक दूसरे से सटे हुए हैं। B (और इसके विपरीत) पर जाकर हम A से C तक प्राप्त कर सकते हैं, इसलिए हम सोच सकते हैं कि A से सीधे B और C दोनों का दौरा अनावश्यक है। दुर्भाग्य से, यह गलत है, क्योंकि यह चित्रण दिखाता है:

चित्र 2

यदि दृष्टांत में दिए गए बिंदु दो अंत बिंदु हैं, तो हम देख सकते हैं कि A से C तक B से होकर हमें एक लंबा रास्ता मिलता है।

इस बारे में कैसा है: यदि हम दोनों चालों का परीक्षण कर रहे हैं AB और AC , तो ABC या ACB का परीक्षण करना अनावश्यक है , क्योंकि उनका परिणाम छोटे पथ नहीं हो सकते। फिर से गलत:

चित्र तीन

मुद्दा यह है कि विशुद्ध रूप से आसन्न-आधारित तर्कों का उपयोग करने से इसमें कटौती नहीं होगी; हमें समस्या की ज्यामिति का भी उपयोग करना होगा। ऊपर दिए गए दो उदाहरणों में क्या आम है (साथ ही बड़े पैमाने पर दूसरा परीक्षण-मामला), यह है कि संलग्न क्षेत्र में एक "छेद" है। यह इस तथ्य में स्वयं को प्रकट करता है कि सीमा पर कुछ बिंदुओं के प्रतिच्छेदन - हमारे "नाखून" - त्रिभुज the एबीसी के भीतर जिनके कोने वृत्त के केंद्र हैं:

चित्र 4

जब ऐसा होता है, तो एक मौका होता है कि से बी और से सी तक जाने के लिए अलग-अलग रास्ते होंगे। इससे भी महत्वपूर्ण बात यह है कि जब ऐसा नहीं होता है (अर्थात यदि A , B और C के बीच कोई अंतर नहीं था ) तो इसकी गारंटी है कि सभी रास्ते ABC और AC से शुरू होते हैं और जो अन्यथा समतुल्य हैं। समान रूप से न्यूनतम पथ में, इसलिए यदि हम B पर जाते हैं तो हमें C को A से सीधे आने की भी आवश्यकता नहीं है ।

यह हमें हमारे उन्मूलन के तरीके की ओर ले जाता है: जब हम एक सर्कल A पर होते हैं , तो हम अपने पास आने वाले हलकों के H की सूची रखते हैं । यह सूची शुरू में खाली है। यदि हम A , B के केंद्रों और H से B के समीप के किसी भी मंडल में बने सभी त्रिकोणों में कोई "नाखून" हैं, तो हम निकटवर्ती वृत्त B पर जाते हैं । यह विधि नाटकीय रूप से उन रास्तों की संख्या को गिराती है जिन्हें हमें पहले टेस्ट-केस में सिर्फ 1 और दूसरे में 10 टेस्ट करने हैं।

कुछ और नोट:

  • हमारे द्वारा आगे भी परीक्षण किए गए पथों की संख्या में कमी संभव है, लेकिन इस समस्या के पैमाने के लिए यह तरीका काफी अच्छा है।

  • मैंने अपने समाधान से रबर-बैंड चुनौती के लिए एल्गोरिथ्म का उपयोग किया । चूंकि यह एल्गोरिथ्म वृद्धिशील है, इसलिए यह बहुत आसानी से पथ-खोज प्रक्रिया में एकीकृत हो सकता है, ताकि हम पथ को कम कर दें क्योंकि हम साथ चलते हैं। चूंकि कई पथ एक प्रारंभिक-खंड साझा करते हैं, इसलिए जब हमारे पास बहुत सारे पथ होते हैं तो यह प्रदर्शन में सुधार कर सकता है। वैध पथ की तुलना में बहुत अधिक मृत-छोर होने पर यह प्रदर्शन को भी नुकसान पहुंचा सकता है। किसी भी तरह से, दिए गए परीक्षण-मामलों के लिए अलग-अलग प्रत्येक पथ के लिए एल्गोरिथ्म का प्रदर्शन काफी अच्छा है।

  • एक किनारे-मामला है जहां यह समाधान विफल हो सकता है: यदि सीमा पर कोई भी बिंदु दो स्पर्शरेखा हलकों के चौराहे का बिंदु है तो कुछ शर्तों के तहत परिणाम गलत हो सकता है। यह रबर-बैंड एल्गोरिदम के काम करने के तरीके के कारण है। कुछ संशोधनों के साथ इन मामलों को संभालना संभव है, लेकिन, नरक, यह पहले से ही काफी लंबा है।


# First test case
I={((32.,42.),64.),((112.,99.),59.),((141.,171.),34.),((157.,191.),28.),((177.,187.),35.),((244.,168.),57.),((289.,119.),20.),((299.,112.),27.),((354.,59.),58.),((402.,98.),23.),((429.,96.),29.),((424.,145.),34.),((435.,146.),20.),((455.,204.),57.),((430.,283.),37.),((432.,306.),48.),((445.,349.),52.),((424.,409.),59.),((507.,468.),64.)}
# Second test case
#I={((32.,42.),64.),((112.,99.),59.),((141.,171.),34.),((157.,191.),28.),((177.,187.),35.),((244.,168.),57.),((289.,119.),20.),((299.,112.),27.),((354.,59.),58.),((402.,98.),23.),((429.,96.),29.),((424.,145.),34.),((435.,146.),20.),((455.,204.),57.),((430.,283.),37.),((432.,306.),48.),((445.,349.),52.),((424.,409.),59.),((507.,468.),64.),((180.,230.),39.),((162.,231.),39.),((157.,281.),23.),((189.,301.),53.),((216.,308.),27.),((213.,317.),35.),((219.,362.),61.),((242.,365.),42.),((288.,374.),64.),((314.,390.),53.),((378.,377.),30.),((393.,386.),34.)}

from numpy import*
V=array;X=lambda u,v:u[0]*v[1]-u[1]*v[0];L=lambda v:dot(v,v)
e=V([511]*2)
N=set()
for c,r in I:
 for C,R in I:
  v=V(C)-c;d=L(v)
  if d:
    a=(r*r-R*R+d)/2/d;q=r*r/d-a*a
    if q>=0:w=V(c)+a*v;W=V([-v[1],v[0]])*q**.5;N|={tuple(t)for t in[w+W,w-W]if all([L(t-T)>=s**2-1e-9 for T,s in I])}
N=map(V,N)
def T(a,b,c,p):H=[X(p-a,b-a),X(p-b,c-b),X(p-c,a-c)];return min(H)*max(H)>=0
def E(a,c,b):
 try:d=max((X(n-a,b-a)**2,id(n),n)for n in N if T(a,b,c,n)*X(n-b,c-b)*X(n-c,a-c))[2];A=E(a,c,d);B=E(d,c,b);return[A[0]+[d]+B[0],A[1]+[sign(X(c-a,b-c))]+B[1]]
 except:return[[]]*2
def P(I,c,r,A):
 H=[];M=[""]
 if L(c-e)>r*r:
    for C,R in I:
     if L(C-c)<=L(r+R)and all([L(h-C)>L(R+s)or any([T(c,C,h,p)for p in N])for h,s in H]):v=V(C);H+=[(v,R)];M=min(M,P(I-{(C,R)},v,R,A+[v]))
    return M
 A+=[e]*2;W=[.5]*len(A)
 try:
  while 1:
    i=[w%1*2or w==0for w in W[2:-2]].index(1);u,a,c,b,v=A[i:i+5];A[i+2:i+3],W[i+2:i+3]=t,_=E(a,c,b);t=[a]+t+[b]
    for p,q,j,k in(u,a,1,i+1),(v,b,-2,i+len(t)):x=X(q-p,c-q);y=X(q-p,t[j]-q);z=X(c-q,t[j]-q);d=sign(j*z);W[k]+=(x*y<=0)*(x*z<0 or y*z>0)*(x!=0 or d*W[k]<=0)*(y!=0 or d*W[k]>=0)*d
 except:return[sum(L(A[i+1]-A[i])**.5for i in range(len(A)-1)),id(A),A]
print V(P(I,e*0,0,[e*0]*2)[2][1:-1])

इनपुट को Iटुपल्स के एक सेट के रूप में चर के माध्यम से दिया जाता है ((x, y), r)जहां (x, y)सर्कल का केंद्र है और rइसका त्रिज्या है। मूल्यों को floatएस होना चाहिए , intएस नहीं । परिणाम को STDOUT में मुद्रित किया जाता है।

उदाहरण

# First test case
I={((32.,42.),64.),((112.,99.),59.),((141.,171.),34.),((157.,191.),28.),((177.,187.),35.),((244.,168.),57.),((289.,119.),20.),((299.,112.),27.),((354.,59.),58.),((402.,98.),23.),((429.,96.),29.),((424.,145.),34.),((435.,146.),20.),((455.,204.),57.),((430.,283.),37.),((432.,306.),48.),((445.,349.),52.),((424.,409.),59.),((507.,468.),64.)}

[[   0.            0.        ]
 [ 154.58723733  139.8329183 ]
 [ 169.69950891  152.76985495]
 [ 188.7391093   154.02738541]
 [ 325.90536774  109.74141936]
 [ 382.19108518  109.68789517]
 [ 400.00362897  120.91319495]
 [ 511.          511.        ]]
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.