एक आत्म-गहन बहुभुज का क्षेत्र


32

2 डी अंतरिक्ष में कोने की एक सूची द्वारा परिभाषित एक संभावित स्व-प्रतिच्छेद बहुभुज पर विचार करें। उदाहरण के लिए

{{0, 0}, {5, 0}, {5, 4}, {1, 4}, {1, 2}, {3, 2}, {3, 3}, {2, 3}, {2, 1}, {4, 1}, {4, 5}, {0, 5}}

ऐसे बहुभुज के क्षेत्र को परिभाषित करने के कई तरीके हैं, लेकिन सबसे दिलचस्प एक समान-विषम नियम है। विमान के किसी भी बिंदु को लेते हुए, बिंदु से अनंत तक (किसी भी दिशा में) एक रेखा खींचें। यदि वह रेखा बहुभुज को विषम संख्या में पार करती है, तो बिंदु बहुभुज के क्षेत्र का हिस्सा है, यदि यह बहुभुज को सम संख्या में पार करता है, तो बिंदु बहुभुज का हिस्सा नहीं है। उपरोक्त उदाहरण बहुभुज के लिए, यहां इसकी रूपरेखा और इसके सम-विषम क्षेत्र दोनों हैं:

रेखांकित करेंक्षेत्र

बहुभुज सामान्य रूप से ऑर्थोगोनल नहीं होगा। मैंने केवल इस तरह के सरल उदाहरण को चुना है ताकि क्षेत्र को गिनना आसान हो सके।

इस उदाहरण का क्षेत्र है 17(नहीं 24या 33अन्य परिभाषाओं के रूप में या क्षेत्र उपज सकता है)।

ध्यान दें कि इस परिभाषा के तहत बहुभुज का क्षेत्र इसके घुमावदार क्रम से स्वतंत्र है।

चुनौती

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

आप STDIN या निकटतम विकल्प, कमांड-लाइन तर्क या फ़ंक्शन तर्क के माध्यम से एक फ़ंक्शन या प्रोग्राम लिख सकते हैं, और परिणाम को वापस कर सकते हैं या इसे STDOUT या निकटतम विकल्प पर प्रिंट कर सकते हैं।

आप किसी भी सुविधाजनक सूची या स्ट्रिंग प्रारूप में इनपुट ले सकते हैं, जब तक कि यह प्रीप्रोसेस न हो।

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

आप उचित डेस्कटॉप मशीन पर 10 सेकंड के भीतर नीचे दिए गए प्रत्येक परीक्षण मामलों को हल करने में सक्षम होना चाहिए। (इस नियम में कुछ नियम है, इसलिए अपने सर्वोत्तम निर्णय का उपयोग करें। यदि यह मेरे लैपटॉप पर 20 सेकंड लेता है तो मैं आपको संदेह का लाभ दूंगा, अगर इसमें एक मिनट लगता है, तो मैं नहीं करूंगा।) मुझे लगता है कि यह सीमा है। यह बहुत उदार होना चाहिए, लेकिन यह उन दृष्टिकोणों को खारिज करने वाला है जहां आप बहुभुज को पर्याप्त रूप से ठीक ग्रिड पर गिनते हैं और मोंटे कार्लो जैसे संभाव्य दृष्टिकोण का उपयोग करते हैं। एक अच्छे खिलाड़ी बनें और इन तरीकों का अनुकूलन करने की कोशिश न करें, ताकि आप समय सीमा को पूरा कर सकें। ;)

आपको सीधे पॉलीगॉन से संबंधित किसी भी मौजूदा फ़ंक्शन का उपयोग नहीं करना चाहिए।

यह कोड गोल्फ है, इसलिए सबसे छोटा सबमिशन (बाइट्स में) जीतता है।

मान्यताओं

  • सभी निर्देशांक रेंज में पूर्णांक हैं 0 ≤ x ≤ 100, 0 ≤ y ≤ 100
  • कम से कम 3और अधिक से अधिक 50कोने में होंगे।
  • कोई भी दोहराव नहीं होगा। न ही कोई कोने दूसरे किनारे पर होगा। ( सूची में ज्वलंत बिंदु हो सकते हैं, हालांकि)

परीक्षण के मामलों

{{0, 0}, {5, 0}, {5, 4}, {1, 4}, {1, 2}, {3, 2}, {3, 3}, {2, 3}, {2, 1}, {4, 1}, {4, 5}, {0, 5}}
17.0000

{{22, 87}, {6, 3}, {98, 77}, {20, 56}, {96, 52}, {79, 34}, {46, 78}, {52, 73}, {81, 85}, {90, 43}}
2788.39

{{90, 43}, {81, 85}, {52, 73}, {46, 78}, {79, 34}, {96, 52}, {20, 56}, {98, 77}, {6, 3}, {22, 87}}
2788.39

{{70, 33}, {53, 89}, {76, 35}, {14, 56}, {14, 47}, {59, 49}, {12, 32}, {22, 66}, {85, 2}, {2, 81},
 {61, 39}, {1, 49}, {91, 62}, {67, 7}, {19, 55}, {47, 44}, {8, 24}, {46, 18}, {63, 64}, {23, 30}}
2037.98

{{42, 65}, {14, 59}, {97, 10}, {13, 1}, {2, 8}, {88, 80}, {24, 36}, {95, 94}, {18, 9}, {66, 64},
 {91, 5}, {99, 25}, {6, 66}, {48, 55}, {83, 54}, {15, 65}, {10, 60}, {35, 86}, {44, 19}, {48, 43},
 {47, 86}, {29, 5}, {15, 45}, {75, 41}, {9, 9}, {23, 100}, {22, 82}, {34, 21}, {7, 34}, {54, 83}}
3382.46

{{68, 35}, {43, 63}, {66, 98}, {60, 56}, {57, 44}, {90, 52}, {36, 26}, {23, 55}, {66, 1}, {25, 6},
 {84, 65}, {38, 16}, {47, 31}, {44, 90}, {2, 30}, {87, 40}, {19, 51}, {75, 5}, {31, 94}, {85, 56},
 {95, 81}, {79, 80}, {82, 45}, {95, 10}, {27, 15}, {18, 70}, {24, 6}, {12, 73}, {10, 31}, {4, 29},
 {79, 93}, {45, 85}, {12, 10}, {89, 70}, {46, 5}, {56, 67}, {58, 59}, {92, 19}, {83, 49}, {22,77}}
3337.62

{{15, 22}, {71, 65}, {12, 35}, {30, 92}, {12, 92}, {97, 31}, {4, 32}, {39, 43}, {11, 40}, 
 {20, 15}, {71, 100}, {84, 76}, {51, 98}, {35, 94}, {46, 54}, {89, 49}, {28, 35}, {65, 42}, 
 {31, 41}, {48, 34}, {57, 46}, {14, 20}, {45, 28}, {82, 65}, {88, 78}, {55, 30}, {30, 27}, 
 {26, 47}, {51, 93}, {9, 95}, {56, 82}, {86, 56}, {46, 28}, {62, 70}, {98, 10}, {3, 39}, 
 {11, 34}, {17, 64}, {36, 42}, {52, 100}, {38, 11}, {83, 14}, {5, 17}, {72, 70}, {3, 97}, 
 {8, 94}, {64, 60}, {47, 25}, {99, 26}, {99, 69}}
3514.46

1
विशेष रूप से, मैं एक तरह से सीमांकक को प्रतिस्थापित करना चाहूंगा जो सूची को एक वैध पोस्टस्क्रिप्ट उपयोगकर्ता पथ बनाता है, इसलिए मैं एक upathऑपरेटर के साथ पूरी बात को पार्स कर सकता हूं । (यह वास्तव में एक अत्यंत सरल है 1: 1 सेपरेटर के बीच रूपांतरण। }, {बस बन जाता है lineto, और एक्स और वाई के बीच अल्पविराम हटा दिया जाता है, और उद्घाटन और समापन ब्रेसिज़ को एक स्थिर हेडर और पाद के साथ बदल दिया जाता है ...)
AJMansfield

1
@AJMansfield मैं आमतौर पर सुविधाजनक, मूल सूची अभ्यावेदन का उपयोग करने में कोई आपत्ति नहीं करता, लेकिन उपयोग upathऔर linetoलगता है जैसे आप वास्तव में इनपुट को प्रीप्रोसेस कर रहे हैं। यानी आप निर्देशांक की सूची नहीं बल्कि एक वास्तविक बहुभुज ले रहे हैं।
मार्टिन एंडर

1
@ मट्टनूनन ओह, यह एक अच्छी बात है। हाँ आप ऐसा मान सकते हैं।
मार्टिन एंडर

2
@ जब दिशा क्रॉसिंग की संख्या को प्रभावित कर सकती है, तो यह केवल 2 की वृद्धि या कमी करेगी, जिससे समानता को संरक्षित किया जा सकता है। मैं एक संदर्भ खोजने की कोशिश करूंगा। एक शुरुआत के लिए, एसवीजी एक ही परिभाषा का उपयोग करता है।
मार्टिन एंडर

1
Mathematica 12.0 में इसके लिए एक नया अंतर्निहित फ़ंक्शन है CrossingPolygon:।
alephalpha

जवाबों:


14

मेथेमेटिका, 247 225 222

p=Partition[#,2,1,1]&;{a_,b_}~r~{c_,d_}=Det/@{{a-c,c-d},{a,c}-b}/Det@{a-b,c-d};f=Abs@Tr@MapIndexed[Det@#(-1)^Tr@#2&,p[Join@@MapThread[{1-#,#}&/@#.#2&,{Sort/@Cases[{s_,t_}/;0<=s<=1&&0<=t<=1:>s]/@Outer[r,#,#,1],#}]&@p@#]]/2&

पहले बहुभुज के प्रतिच्छेदन के बिंदुओं को जोड़ें, फिर कुछ किनारों को उल्टा करें, फिर उसके क्षेत्र की गणना एक साधारण बहुभुज की तरह की जा सकती है।

यहाँ छवि विवरण दर्ज करें

उदाहरण:

In[2]:= f[{{15, 22}, {71, 65}, {12, 35}, {30, 92}, {12, 92}, {97, 31}, {4, 32}, {39, 43}, {11, 40}, 
 {20, 15}, {71, 100}, {84, 76}, {51, 98}, {35, 94}, {46, 54}, {89, 49}, {28, 35}, {65, 42}, 
 {31, 41}, {48, 34}, {57, 46}, {14, 20}, {45, 28}, {82, 65}, {88, 78}, {55, 30}, {30, 27}, 
 {26, 47}, {51, 93}, {9, 95}, {56, 82}, {86, 56}, {46, 28}, {62, 70}, {98, 10}, {3, 39}, 
 {11, 34}, {17, 64}, {36, 42}, {52, 100}, {38, 11}, {83, 14}, {5, 17}, {72, 70}, {3, 97}, 
 {8, 94}, {64, 60}, {47, 25}, {99, 26}, {99, 69}}]

Out[2]= 3387239559852305316061173112486233884246606945138074528363622677708164\
 6419838924305735780894917246019722157041758816629529815853144003636562\
 9161985438389053702901286180223793349646170997160308182712593965484705\
 3835036745220226127640955614326918918917441670126958689133216326862597\
 0109115619/\
 9638019709367685232385259132839493819254557312303005906194701440047547\
 1858644412915045826470099500628074171987058850811809594585138874868123\
 9385516082170539979030155851141050766098510400285425157652696115518756\
 3100504682294718279622934291498595327654955812053471272558217892957057\
 556160

In[3]:= N[%] (*The numerical value of the last output*)

Out[3]= 3514.46

दुर्भाग्य से मुझे यकीन नहीं है कि यह तर्क सभी स्थितियों के लिए काम करेगा। क्या आप कोशिश कर सकते हैं {1,2},{4,4},{4,2},{2,4},{2,1},{5,3}? आपको 3.433333333333309 के साथ बाहर आना चाहिए। मैंने एक समान तर्क का उपयोग करते हुए देखा।
मिकाइ

@ मिक्की हाँ, यह काम करता है। यह लौटा 103/30, और संख्यात्मक मान है 3.43333
एलेफाल्फा

उसके लिए माफ़ करना। अच्छा समाधान
मिकी

44

अजगर 2, 323 319 बाइट्स

exec u"def I(s,a,b=1j):c,d=s;d-=c;c-=a;e=(d*bX;return e*(0<=(b*cX*e<=e*e)and[a+(d*cX*b/e]or[]\nE=lambda p:zip(p,p[1:]+p);S=sorted;P=E(input());print sum((t-b)*(r-l)/2Fl,r@E(S(i.realFa,b@PFe@PFi@I(e,a,b-a)))[:-1]Fb,t@E(S(((i+j)XFe@PFi@I(e,l)Fj@I(e,r)))[::2])".translate({70:u" for ",64:u" in ",88:u".conjugate()).imag"})

निम्नलिखित रूप में STDIN के माध्यम से जटिल संख्या के रूप में कोने की सूची लेता है

[  X + Yj,  X + Yj,  ...  ]

, और परिणाम STDOUT को लिखता है।

स्ट्रिंग प्रतिस्थापन और कुछ रिक्ति के बाद समान कोड:

def I(s, a, b = 1j):
    c, d = s; d -= c; c -= a;
    e = (d*b.conjugate()).imag;
    return e * (0 <= (b*c.conjugate()).imag * e <= e*e) and \
           [a + (d*c.conjugate()).imag * b/e] or []

E = lambda p: zip(p, p[1:] + p);
S = sorted;

P = E(input());

print sum(
    (t - b) * (r - l) / 2

    for l, r in E(S(
        i.real for a, b in P for e in P for i in I(e, a, b - a)
    ))[:-1]

    for b, t in E(S(
        ((i + j).conjugate()).imag for e in P for i in I(e, l) for j in I(e, r)
    ))[::2]
)

व्याख्या

इनपुट बहुभुज (कोने सहित) के दो पक्षों के प्रतिच्छेदन के प्रत्येक बिंदु के लिए, उस बिंदु पर एक ऊर्ध्वाधर रेखा पास करें।

आकृति 1

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

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

कुल मिलाकर, यह एक ( एन 3 लॉग एन ) एल्गोरिदम है।


4
ये जबरदस्त है! मुझे पता था कि मैं इस एक के लिए आप पर भरोसा कर सकता हूं। ;) (आप स्टैक ओवरफ्लो पर इस सवाल का जवाब देना चाह सकते हैं ।)
मार्टिन एंडर

@ MartinBüttner रखें उन्हें आ रहा :)
Ell

7
महान काम और एक महान विवरण
मिकी

1
यह एक प्रभावशाली उत्तर है। क्या आपने स्वयं एल्गोरिथ्म विकसित किया है या इस समस्या पर मौजूदा काम है? यदि मौजूदा काम है, तो मैं एक पॉइंटर की सराहना करूंगा जहां मुझे मिल सकता है। मुझे इससे निपटने का कोई अंदाजा नहीं था।
लॉजिक नाइट

5
@CarpetPython मैंने इसे खुद विकसित किया है, लेकिन अगर यह पहले नहीं किया गया है तो मुझे बहुत आश्चर्य होगा।
इल

9

हास्केल, 549

ऐसा नहीं लगता है कि मैं इसे काफी दूर तक घेर सकता हूं, लेकिन अवधारणा अन्य दो उत्तरों से अलग थी इसलिए मुझे लगा कि मैं इसे वैसे भी साझा करूंगा। यह क्षेत्र की गणना करने के लिए O (N ^ 2) तर्कसंगत संचालन करता है।

import Data.List
_%0=2;x%y=x/y
h=sort
z f w@(x:y)=zipWith f(y++[x])w
a=(%2).sum.z(#);(a,b)#(c,d)=b*c-a*d
(r,p)?(s,q)=[(0,p)|p==q]++[(t,v t p r)|u t,u$f r]where f x=(d q p#x)%(r#s);t=f s;u x=x^2<x
v t(x,y)(a,b)=(x+t*a,y+t*b);d=v(-1)
s x=zip(z d x)x
i y=h.(=<<y).(?)=<<y
[]!x=[x];x!_=x
e n(a@(x,p):y)|x>0=(n!y,a):(e(n!y)$tail$dropWhile((/=p).snd)y)|0<1=(n,a):e n y
c[p]k=w x[]where((_,q):x)=e[]p;w((n,y):z)b|q==y=(k,map snd(q:b)):c n(-k)|0<1=w z(y:b);c[]_=[]
b(s,p)=s*a p
u(_,x)(_,y)=h x==h y
f p=abs$sum$map b$nubBy u$take(length p^2)$c[cycle$i$s p]1

उदाहरण:

λ> f test''
33872395598523053160611731124862338842466069451380745283636226777081646419838924305735780894917246019722157041758816629529815853144003636562916198543838905370290128618022379334964617099716030818271259396548470538350367452202261276409556143269189189174416701269586891332163268625970109115619 % 9638019709367685232385259132839493819254557312303005906194701440047547185864441291504582647009950062807417198705885081180959458513887486812393855160821705399790301558511410507660985104002854251576526961155187563100504682294718279622934291498595327654955812053471272558217892957057556160
λ> fromRational (f test'')
3514.4559380388832

विचार हर क्रॉसिंग पर बहुभुज को फिर से स्थापित करने का है, जिसके परिणामस्वरूप बहुभुजों का एक संघ है जिसमें कोई प्रतिच्छेद किनारों नहीं हैं। फिर हम गॉल के शॉलेस फॉर्मूला ( http://en.wikipedia.org/wiki/Shoelace_formula ) का उपयोग करके बहुभुजों में से प्रत्येक के (हस्ताक्षरित) क्षेत्र की गणना कर सकते हैं । सम-विषम नियम मांग करता है कि जब एक क्रॉसिंग को परिवर्तित किया जाता है, तो नए बहुभुज का क्षेत्र पुराने बहुभुज के सापेक्ष नकारात्मक रूप से गिना जाता है।

उदाहरण के लिए, मूल प्रश्न में बहुभुज पर विचार करें। ऊपरी-बाएं में क्रॉसिंग को दो रास्तों में परिवर्तित किया जाता है जो केवल एक बिंदु पर मिलते हैं; दो रास्ते दोनों उन्मुख दक्षिणावर्त हैं, इसलिए प्रत्येक के क्षेत्र सकारात्मक होंगे जब तक कि हमने यह घोषित नहीं किया कि आंतरिक पथ बाहरी मार्ग के सापेक्ष -1 से भारित है। यह अल्फ़ाल्फा के पथ के उलट के बराबर है।

मूल उदाहरण से प्राप्त बहुभुज

एक अन्य उदाहरण के रूप में, मिकी की टिप्पणी से बहुभुज पर विचार करें:

पॉलीगन्स मिकी की टिप्पणी से प्राप्त हुए हैं

यहाँ, कुछ बहुभुज दक्षिणावर्त और कुछ वामावर्त उन्मुख हैं। साइन-फ्लिप-ऑन-क्रॉसिंग नियम यह सुनिश्चित करता है कि दक्षिणावर्त-उन्मुख क्षेत्र -1 का अतिरिक्त कारक उठाते हैं, जिससे उन्हें क्षेत्र में सकारात्मक राशि का योगदान मिलता है।

यहां बताया गया है कि कार्यक्रम कैसे काम करता है:

import Data.List  -- for sort and nubBy

-- Rational division, with the unusual convention that x/0 = 2
_%0=2;x%y=x/y

-- Golf
h=sort

-- Define a "cyclic zipWith" operation. Given a list [a,b,c,...z] and a binary
-- operation (@), z (@) [a,b,c,..z] computes the list [b@a, c@b, ..., z@y, a@z]
z f w@(x:y)=zipWith f(y++[x])w

-- The shoelace formula for the signed area of a polygon
a=(%2).sum.z(#)

-- The "cross-product" of two 2d vectors, resulting in a scalar.
(a,b)#(c,d)=b*c-a*d

-- Determine if the line segment from p to p+r intersects the segment from
-- q to q+s.  Evaluates to the singleton list [(t,x)] where p + tr = x is the
-- point of intersection, or the empty list if there is no intersection. 
(r,p)?(s,q)=[(0,p)|p==q]++[(t,v t p r)|u t,u$f r]where f x=(d q p#x)%(r#s);t=f s;u x=x^2<x

-- v computes an affine combination of two vectors; d computes the difference
-- of two vectors.
v t(x,y)(a,b)=(x+t*a,y+t*b);d=v(-1)

-- If x is a list of points describing a polygon, s x will be the list of
-- (displacement, point) pairs describing the edges.
s x=zip(z d x)x

-- Given a list of (displacement, point) pairs describing a polygon's edges,
-- create a new polygon which also has a vertex at every point of intersection.
-- Mercilessly golfed.
i y=h.(=<<y).(?)=<<y


-- Extract a simple polygon; when an intersection point is reached, fast-forward
-- through the polygon until we return to the same point, then continue.  This
-- implements the edge rewiring operation. Also keep track of the first
-- intersection point we saw, so that we can process that polygon next and with
-- opposite sign.
[]!x=[x];x!_=x
e n(a@(x,p):y)|x>0=(n!y,a):(e(n!y)$tail$dropWhile((/=p).snd)y)|0<1=(n,a):e n y

-- Traverse the polygon from some arbitrary starting point, using e to extract
-- simple polygons marked with +/-1 weights.
c[p]k=w x[]where((_,q):x)=e[]p;w((n,y):z)b|q==y=(k,map snd(q:b)):c n(-k)|0<1=w z(y:b);c[]_=[]

-- If the original polygon had N vertices, there could (very conservatively)
-- be up to N^2 points of intersection.  So extract N^2 polygons using c,
-- throwing away duplicates, and add up the weighted areas of each polygon.
b(s,p)=s*a p
u(_,x)(_,y)=h x==h y
f p=abs$sum$map b$nubBy u$take(length p^2)$c[cycle$i$s p]1
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.