Çokgenin dışbükey olup olmadığını belirleme


21

Giriş poligonunun dışbükey olup olmadığını belirlemek için bir program yazın . Çokgen, N içeren bir satır , köşelerin sayısı, ardından her köşenin x ve y koordinatlarını içeren N satırlarıyla belirtilir . Köşeler, isteğe bağlı bir tepe noktasından başlayarak saat yönünde listelenir.

örnek 1

giriş

4
0 0
0 1
1 1
1 0

çıktı

convex

örnek 2

giriş

4
0 0
2 1
1 0
2 -1

çıktı

concave

örnek 3

giriş

8
0 0
0 1
0 2
1 2
2 2
2 1
2 0
1 0

çıktı

convex

x ve y tamsayıları, N <1000 ve | x |, | y | <1000'dir . Giriş poligonunun basit olduğunu varsayabilirsiniz (kenarların hiçbiri geçmez, sadece 2 kenar her köşeye temas eder). En kısa program kazanır.


"Basit", "ardışık kenarlar collinear değildir" içermez ?! Ayrıca birkaç test sonucu: (0,0) (0,2) (2,2) (2,0) (1,1); ve (1,1) (0,0) (0,2) (2,2) (2,0) - içbükey tepe noktasını bulmanın uçtan başa başa sarılmasını gerektiren durumları test etmek için.
Peter Taylor

Bu soru eskimektedir, ancak ... İki hizalanmış kesime sahip içbükey bir örnek eklemeyi düşünün, örneğin örnek 2'nin bir modifikasyonu: (0,0), (2,1), (4,2), (1,0) ( 2, 1). Bunu ortaya koydum, çünkü örnek 3'ün etrafında farkında olmadan fışkırdım.
Jesse Millikan

Yanıtlar:


4

J, 105

echo>('concave';'convex'){~1=#=(o.1)([:>-.~)(o.2)|3([:-/12 o.-@-/@}.,-/@}:)\(,2&{.)j./"1}.0&".;._2(1!:1)3

Yukarıdaki üç testi de geçer.

Düzenleme: (111-> 115) Pi açısını kaldırarak eş doğrusal noktaları kullanın. Başka bir yerde birkaç karakter kazandı.

Düzenleme: (115-> 105) Daha az dilsiz.

J engelli için açıklama:

  • (1!:1)3STDIN ila EOF'ı okuyun. (Bence.)
  • 0&".;._2 bu tür bir girişi ayrıştırmak için güzel bir deyimdir.
  • j./"1}. ilk girdi satırını (N 0) devre dışı bırakır ve çiftleri komplekslere dönüştürür.
  • (,2&{.) listenin sonuna ilk iki noktayı işaretleyin.
  • 3(f)\ f uzunluğu 3 olan kayan pencereye uygulanır (açı için 3 puan)
  • [:-/12 o.-@-/@}.,-/@}: her 3 noktayı -pi ve pi arasında bir açıya dönüştüren bir fiildir.
    • -@-/@}.,-/@}:(p1 - p2) üretir (p3 - p2). (Bunların karmaşık olduğunu hatırlayın.)
    • 12 o. her kompleks için bir açı verir.
    • [:-/(...) İki açının farkını verir.
  • (o.1)([:>-.~)(o.2)| mod 2 pi, pi açısını ortadan kaldırır (düz bölümler) ve pi ile karşılaştırılır (noktaların bir yönde sarılması gerekmediği sürece önemli değildir).
  • 1=#= Tüm bu karşılaştırma sonucu 1 veya 0 ise (Kendi kendini sınıflandır ile. Bu aptalca görünüyor.)
  • echo>('concave';'convex'){~ dışbükey yazdırın.

3

Python - 149 karakter

p=[map(int,raw_input().split())for i in[0]*input()]*2
print'ccoonncvaevxe'[all((a-c)*(d-f)<=(b-d)*(c-e)for(a,b),(c,d),(e,f)in zip(p,p[1:],p[2:]))::2]

Sanırım <= ihtiyacınız var, az önce eklediğim örnek 3'e bakın.
Keith Randall

1
kahretsin, o dilim ...
st0le

2

Ruby 1.9, 147 133 130 124 123

gets
puts ($<.map{|s|s.split.map &:to_i}*2).each_cons(3).any?{|(a,b),(c,d),(e,f)|(e-c)*(d-b)<(d-f)*(a-c)}?:concave: :convex

1

scala: 297 karakter

object C{class D(val x:Int,val y:Int)
def k(a:D,b:D,c:D)=(b.y-a.y)*(c.x-b.x)>=(c.y-b.y)*(b.x-a.x) 
def main(a:Array[String]){val s=new java.util.Scanner(System.in)
def n=s.nextInt
val d=for(x<-1 to n)yield{new D(n,n)}print((true/:(d:+d.head).sliding(3,1).toList)((b,t)=>b&&k(t(0),t(1),t(2))))}}

1
Sen kullanarak üç karakterlerin tıraş edebilirsiniz def main(a:...yerine def main(args:....
Gareth,

Evet, kendimi farkettim, ama 299 - 149 beni başkasının yanına getirmiyor. Belki başka iyileştirmeler de bulursam - ah, bir tane var: n bir fonksiyon ismi (bir sonraki) ve bir değişken isim.
kullanıcı bilinmeyen,
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.