Kazları Yok Olma Açısından Kurtarın


13

Alex A olarak bilinen kaz türlerinin 64 hücreden oluşan üçgen ızgaralarda bulunduğu bilinir:

Hücreler
(Bu alakasız Project Euler probleminden çekilen resim .)

Biz sayılarla her hücreyi etiketleyeceğim 0için 63aşağıda her satırda soldan sağa hareket eden, sonra üst sıradan başlayarak. Yani üst hücre 0ve sağ alt hücre 63.

Her hücrenin üç sınırı vardır. Biz formdaki her sınır etiketleyebilir a,bnerede ave bhücrelerin sayıları payı olduğunu sınırına yönünde. Örneğin, hücre 0ile arasındaki sınır 2denir 0,2veya 2,0(hangi sıraya koyduğunuz önemli değildir).

Izgaranın en kenarındaki kenarlıklar için etiketleme sistemi farklıdır, çünkü ızgaranın kenarındaki hücreler diğer hücrelerle paylaşmadıkları bir sınıra sahiptir. Bir kenarlık yalnızca bir hücrenin parçasıysa, harfi kullanırız X. Örneğin, hücrenin üç sınırları 0vardır 0,2, 0,Xve 0,X.

Bazı hücreler kaz içerir . Ancak, bu kazlar, onları korumazsanız kötü tilkiler (ızgara sınırlarının dışından gelen) tarafından öldürülecektir. Ve eğer tüm kazlar ölürse BrainSteel üzülür. Bu nedenle, onları tilkilerden korumak için kazların etrafına çitler inşa eden bir program yazacağız. Kazlar, tamamen kapalı tek bir çokgen çitinde bulunmalıdır . Çit bütçemiz oldukça düşük olduğundan mümkün olan en az sayıda çit kullanın.

Giriş Açıklaması

Numaralarının listesi, virgül, ayrılmış 0için 63kazlar içeren hücreleri temsil eden. Misal:

6,12

Çıktı Açıklaması

Kazları başarılı bir şekilde korumak için çitlerin üzerine inşa edilmesi gereken sınırların bir listesi. Bu mümkün olan en az sayıda çit olmalıdır. Misal:

5,6 6,7 11,12 12,13 

"Kazlar tamamen kapalı bir çit poligonunda bulunmalıdır." Tüm kazlar aynı poligonda mı yaşamalıdır, yoksa birden çok (veya 0) çokgen olabilir mi?
feersum

@feersum Bütün kazlar aynı poligonda yaşamalıdır. Soruyu açıklığa kavuşturmak için düzenledim.
absinthe

@Katya Çokgenin kendiliğinden kesişme noktaları veya sıfır genişlikte kesitler olabilir mi? Bir kum saati şekli gibi düşünün.
orlp

@orlp Sıfır genişlikli bölüm nedir?
Absinthe

2
@orlp Çokgen sıfır genişlikte bölümler içermemelidir.
Absinthe

Yanıtlar:


10

C #, 530 bayt

C # programını tamamlayın, girişi STDIN'den tek bir satır olarak alır ve arkadaki "" ile STDOUT'a tek bir satır çıkarır.

Bu oldukça uzun ... ve çok fazla x / y / z tekrarı var, ama şimdiye kadar mantıklı bir şeye indiremedim ve 2 saat içinde bir sınavım var, bu yarına geri gelebilir.

using Q=System.Console;class P{static void Main(){int q=9,w=0,e=9,r=0,t=9,u=0,i=0,x=0,y=0,z=0,p=0;System.Action V=()=>{z=(int)System.Math.Sqrt(i);p=(x=i-z*z)%2;x/=2;y=(++z*z--+~i)/2;},W=()=>{Q.Write(i+","+(x<0|y++<0|z>7?"X":""+(z*z+2*x+1-p))+" ");};foreach(var g in Q.ReadLine().Split(',')){i=int.Parse(g);V();q=q>x?x:q;w=w<x?x:w;e=e>y?y:e;r=r<y?y:r;t=t>z?z:t;u=u<z?z:u;}for(i=64;i-->0;){V();if(!(x<q|x>w|y<e|y>r|z<t|z>u))if(p>0){if(y==r)W();if(x++==w)W();x--;if(z--==t)W();}else{if(y--==e)W();if(x--==q)W();x++;if(z++==u)W();}}}}

Bu şema neler olup bittiğini açıklamaktadır.

Örnek çözüm gösteren, x / y / z / (p) olarak tanımlanan ızgara

0 genişlikli bölümlere sahip olamadığımızdan, bir "altıgen" in her zaman en ucuz şekil olacağını (ve kazlara hareket etmek için maksimum alan sağlama avantajına sahip olacağını) unutmayın.

Program ilk olarak tüm giriş hücresi indekslerini x / y / z koordinatlarına çevirerek ve x / y / z'nin her birinin min / max'ını bularak çalışır.

z = floor(root(i))
x = floor((i - z^2) / 2)
y = floor((z+1)^2 - i - 1) / 2)
p = (i - z^2) % 2

Daha sonra, her bir hücre indeksinden geçer ve tarif ettiğimiz 'altıgen' sınırına uyup uymadığını kontrol eder. Öyleyse, sınırların uç kenarlarından herhangi birinde olup olmadığını kontrol eder (yani x = xmin veya y = ymax) ve varsa karşılık gelen kenarları ekler. Yanındaki kenarın dizinini bulmalıdır. X ve z için, onları istediğimiz gibi artırırız / azaltırız ve sonra aşağıdaki formülü kullanırız:

i = z^2 + 2*x + (1-p)

"Eşlik" in her zaman değiştiğine ve y'nin dahil olmadığına dikkat edin. Y için, hiçbir şeyi değiştirmek zorunda değiliz, ancak kod biraz karışıklıktır, çünkü sonraki kapının hücresinin "X" olup olmadığını tespit etmek için "üçgen" sınırları kontrol etmesi gerekir.

Örnek çözüm (Üç köşeden kazlı hücreler):

Input
2,50,62

Output
62,63 61,X 59,X 57,X 55,X 53,X 51,X 50,49 48,X 36,X 35,X 25,X 24,X 16,X 15,X 9,X 8,X 4,X 3,X 2,0 1,X 

Yorumlar içeren düzen kodu:

using Q=System.Console;

class P
{
    static void Main()
    {
        int q=9,w=0,e=9,r=0,t=9,u=0, // min/max x/y/z/ (init min high, and max low)
        i=0, // index of cell we are looking at
        x=0,y=0,z=0,p=0; // x,y,z dimension

        System.Action V=()=>
            { // translates the index into x/y/z/p
                z=(int)System.Math.Sqrt(i);
                p=(x=i-z*z)%2; // 'parity'
                x/=2; // see p assignment
                y=(++z*z--+~i)/2; // ~i == -i - 1
            },
            W=()=>
            { // writes out the edge of i, and the cell described by x/z/inverse of p   (the inversion of p handles y +/-)
                Q.Write(i+","+ // write out the edge
                        (x<0|y++<0|z>7?"X":""+(z*z+2*x+1-p)) // either X (if we go out of 'trianlge' bounds), or we translate x/z/inverse of p into an index
                        +" "); // leaves a trailing space (as shown in example output)
            };

        foreach(var g in Q.ReadLine().Split(',')) // for each cell with geese
        {
            i=int.Parse(g); // grab index of cell
            V(); // compute x/y/z/p
            q=q>x?x:q; // sort out mins/maxes
            w=w<x?x:w;
            e=e>y?y:e;
            r=r<y?y:r;
            t=t>z?z:t;
            u=u<z?z:u;

            // code like the above suggests a solution with a couple of arrays would be better...
            // I've not had success with that yet, but maybe in a couple of days I will try again
        }

        for(i=64;i-->0;) // for each cell
        {
            V(); // compute x/y/z/p
            if(!(x<q|x>w|y<e|y>r|z<t|z>u)) // if we are inside the 'hex' bounds
                if(p>0)
                { // x max, y max, z min
                    // these checks check that we are on the extremes of the 'hex' bounds,
                    // and set up the appropriate vars for W calls to put the edges in
                    // must do y first, because W modifies it for us (saves 2 bytes in the next block)
                    if(y==r) // don't need the ++ (can't go out of 'trianlge' bounds)
                        W();
                    if(x++==w)
                        W();
                    x--;
                    if(z--==t)
                        W();
                    //z++; not used again
                }
                else
                { // x min, y min, z max
                    if(y--==e) // do need the -- (used for 'trianlge' bounds checking)
                        W();
                    // y is reset in W, as such
                    if(x--==q)
                        W();
                    x++;
                    if(z++==u)
                        W();
                    //z--; not used again
                }
        }
    }
}

İle bir bayt kaydedebilirsiniz using System;.
LegionMammal978

@ LegionMammal978 infact bunu yaparak iki kazanır .. Sadece Q.Write ve Q.ReadLine için kullanır. bunlar ve şimdi sahip olduğu kullanım ifadesi using Q=System.Console;Q.Write();Q.ReadLine()(45 Bayt) öneriniz using System;Console.Write();Console.ReadLine()(47 Bayt).
Kade

Ayrıca, değil gereksiz yere başlatarak 10 bayt bırakabilirsiniz i, x, y, z, ve p0'a
LegionMammal978

@ LegionMammal978 emin misin? Bunu denedim ve atanmamış bir vavable kullanmak için hata veriyor.
Kade

@ Vioz- Hangi değişkenler? Açıklamalı sürümdeki hangi satırlar?
LegionMammal978
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.