Ç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.