Första tanken vid ett sådant här problem är ju att man kan ha en stor boolean-matris där man för varje rektangel täcker över motsvarande område i matrisen, och sedan beräknar omkretsen på slutet. Men det går inte i detta fall, minnet räcker helt enkelt inte.

Istället kan man tillverka en sorterad tabell över intressanta x-värden, d.v.s. där rektanglarna börjar eller slutar. Sedan "scannar" man över väggen från vänster till höger och samlar på sig små omkrets-fragment som man hela tiden adderar. För att hålla koll på hur mönstret egentligen ser ut behöver man en array i y-led C[-10000..10000] där varje element betyder hur många rektanglar man är inne i för tillfället. Varje gång man kommer till ett x-värde i tabellen som är en rektangels vänsterkant, ökar man C[y]-värdena för alla y mellan toppen och botten på den aktuella rektangeln. Och tvärtom: när man når en rektangels högerkant går man ut ur rektangeln och minskar C[y] för y-värdena.

För varje gång du tar ett nytt x-värde adderar du följande omkretsfragment:

Horisontella fragment: (räknas ut innan C-arrayen modifieras)
Du gör en vertikal scan i C-arrayen och räknar ut hur många gånger du passerar en 0-1 eller 1-0 -övergång. Dessa övergångar motsvarar de kanter som verkligen "syns". Det blir givetvis ett jämnt tal eftersom du börjar och slutar på C[y] = 0. Detta tal multipliceras med hur långt du har gått i x-led, d.v.s. differensen mellan det aktuella x-värdet och det förra.

Vertikala fragment: (räknas ut samtidigt som C-arrayen modifieras)
När du går igenom y-värdena för den rektangel som börjar eller slutar, kollar du om din ändring av C[y] är en 1-0-ändring eller en 0-1 -ändring. I så fall motsvarar detta en synlig kant, och du adderar 1 till omkretsen.

Detta beskriver en ungefärlig algoritm. Fortfarande återstår detaljerna, t.ex. hur du representerar att y-värdena som gäller i C-arrayen är "pixlar" medan rektanglarna ges av koordinater "mellan pixlarna". Dessutom måste du tänka över hur du ska göra när flera rektanglar börjar eller slutar på samma x-värde.

Tillbaka