Kokonaispisteet kolmiossa

Anonyymi

Annettuna on positiiviset kokonaisluvut a, b ja n.
Tehtävänä on laskea kuinka monta on kokonaislukupareja (x, y), joille x, y>=1 ja ax by<=n.

Laskenta-algoritmin tulisi olla sen verran tehokas, että se selviää jopa suuruusluokkaa n=10^100 olevista tapauksista (joissa a ja b ovat esim. alle 1000).

5

57

    Vastaukset

    Anonyymi (Kirjaudu / Rekisteröidy)
    5000
    • Anonyymi

      Helppo integroida paloittain ja käyttää sitten aritmeettista summakaavaa ja lisätä lopuksi vajaajaksoinen osuus.

      n = 1234567890#12#3#4#567890123456789012345678901234567890123456789012345678901234567890
      b = 779
      a = 883
      ab = a*b
      m = n - n % ab
      p = m//ab
      c = 0
      for x in range(1,b 1): c = (n-x*a)//b
      cc = p*(c-(p-1)*ab c)//2
      c = 0
      for x in range(m//a 1,n//a 1): c = (n-x*a)//b
      print(c)
      cc = c
      print(cc)


      Ei yhtään sisennystä. Voi kopsata suoran. Aikaa kuluu isoilla luvuilla lähinnä tulostamiseen.

      Toiminnan voi testata pienillä luvuilla yksinkertaisella varmasti toimivalla integrointisilmukalla:

      n = 123456789012#3#4
      b = 779
      a = 883
      c = 0
      for x in range(1,n//a 1): c = (n-x*a)//b
      print (a,b,n,c)

      Kannattaa käyttää Pypyä. Yli 30 kertainen nopeutus. Jos käyttää Python 2:sta, range on korvattava xrange:lla. Silmukka lyhenee, jos laittaa isomman luvun aina a:ksi. Aluksi kannattaa kokeilla "pienillä" n//a arvoilla, jotta näkee mihin kone pystyy. Heti kun c kasvaa yli 63-bittiseksi, toiminta hidastuu.

      • Anonyymi

        Joo, hyvin toimii. Muuten, jos korvaa summaussilmukan sum():lla, niin ei tarvitse välittää onko x- vai range ja eikös se olisi Pythonmaisempaa? Eli esim.

        c = 0
        for x in range(1,b 1): c = (n-x*a)//b

        voisi korvata

        c = sum((n-x*a)//b for x in range(1, b 1))


      • Anonyymi
        Anonyymi kirjoitti:

        Joo, hyvin toimii. Muuten, jos korvaa summaussilmukan sum():lla, niin ei tarvitse välittää onko x- vai range ja eikös se olisi Pythonmaisempaa? Eli esim.

        c = 0
        for x in range(1,b 1): c = (n-x*a)//b

        voisi korvata

        c = sum((n-x*a)//b for x in range(1, b 1))

        Ei Python 2:n range-ongelma mihinkään katoa tuon sum:in kanssa. Siihähän on se ihan sama range. Eikä mitään ongelmaa ei ole pienillä range-arvoilla. b 1 on mitättömän pieni!

        Kokeile joksus Python 2:lla:
        for x in range(0,1234567890):

        Pienennä rangea sitten, kunnes ei tule enää muisti-erroria ja katso sitten montako Gtavua kuluu muistia. Kokeile sitten xrangella. Ei kulu yhtään muistia!

        Pypyn kanssa ei kannata ikinä käyttää mitään turhia erikoiskäskyjä tai rakenteita tai kirjasto-ohjelmia. Nytkin tuli sum:n kanssa yli kaksinkertainen hidastus. Sai odottaa minuuttikaupalla valmistumista. Kokeile sillä lopussa olevalla perusohjelmalla.

        Miten lisäät tilapäisiä testitulostuksia tuon sum:n kanssa? Niitä tarvitaan aina. Jotain iloa saatta olla joissakin erikoistilanteissa.

        Tiedätkö yhtään varmaa tulosta, jos n on yli 20-numeroinen?


      • Anonyymi
        Anonyymi kirjoitti:

        Ei Python 2:n range-ongelma mihinkään katoa tuon sum:in kanssa. Siihähän on se ihan sama range. Eikä mitään ongelmaa ei ole pienillä range-arvoilla. b 1 on mitättömän pieni!

        Kokeile joksus Python 2:lla:
        for x in range(0,1234567890):

        Pienennä rangea sitten, kunnes ei tule enää muisti-erroria ja katso sitten montako Gtavua kuluu muistia. Kokeile sitten xrangella. Ei kulu yhtään muistia!

        Pypyn kanssa ei kannata ikinä käyttää mitään turhia erikoiskäskyjä tai rakenteita tai kirjasto-ohjelmia. Nytkin tuli sum:n kanssa yli kaksinkertainen hidastus. Sai odottaa minuuttikaupalla valmistumista. Kokeile sillä lopussa olevalla perusohjelmalla.

        Miten lisäät tilapäisiä testitulostuksia tuon sum:n kanssa? Niitä tarvitaan aina. Jotain iloa saatta olla joissakin erikoistilanteissa.

        Tiedätkö yhtään varmaa tulosta, jos n on yli 20-numeroinen?

        Joo sori, siellähän se sama range on sisällä. Tajusin just vähän aikaa sitten itsekin. Jotenkin ajattelin, että sum():ssa on niinkuin oma juttunsa, mutta iterable:han sille pitää antaa.

        Niin kieltämättä sitä aina huomaa että haluaisi lisätä tulostuksen tai jotain muuta, niin se pitää muuttaa kun sen on tehnyt sum():lla, lambda:na, listakoostamisena tms.

        Olen melko varma esim. tuloksesta

        31081669306331872406696219768357999389733129838639415077188983595219295535916013

        parametreille

        a = 712
        b = 129
        n = 2389472394671246172423847923847289461284627


      • Anonyymi
        Anonyymi kirjoitti:

        Joo sori, siellähän se sama range on sisällä. Tajusin just vähän aikaa sitten itsekin. Jotenkin ajattelin, että sum():ssa on niinkuin oma juttunsa, mutta iterable:han sille pitää antaa.

        Niin kieltämättä sitä aina huomaa että haluaisi lisätä tulostuksen tai jotain muuta, niin se pitää muuttaa kun sen on tehnyt sum():lla, lambda:na, listakoostamisena tms.

        Olen melko varma esim. tuloksesta

        31081669306331872406696219768357999389733129838639415077188983595219295535916013

        parametreille

        a = 712
        b = 129
        n = 2389472394671246172423847923847289461284627

        Jos vaihtaa a:n ja b:n arvot, tuloksen on tietysti oltava sama. Jos ohjelmassa a ja b ovat epäsymmetrisesti, niin olisiko viallisen ohjelman mahdollista tuottaa molemmilla tavoilla aina sama tulos? Ja useilla eri a:n ja b:n ja n:n arvoilla.


    Ketjusta on poistettu 0 sääntöjenvastaista viestiä.

    Luetuimmat keskustelut

    1. Euroviisut fiasko, Suomen kautta aikain typerin esitys, jumbosija odottaa. Olisi pitänyt boikotoida!

      Tämän vuoden euroviisut on monella tapaa täydellinen fiasko. Ensinnäkin kaikkien itseään kunnioittavien eurooppalaisten
      Maailman menoa
      314
      3856
    2. 209
      3068
    3. Hei A, osaatko

      sanoa, miksi olet ihan yhtäkkiä ilmestynyt kaveriehdotuksiini Facebookissa? Mitähän kaikkea Facebook tietää mitä minä en
      Ikävä
      72
      2604
    4. Synnittömänä syntyminen

      Helluntailaisperäisillä lahkoilla on Raamatunvastainen harhausko että ihminen syntyy synnittömänä.
      Helluntailaisuus
      242
      2054
    5. Tuollainen kommentti sitten purjehduspalstalla

      "Naisen pillu se vasta Bermudan kolmio on. Sinne kun lähdet soutelemaan niin kohta katoaa sekä elämänilo että rahat"
      Suhteet
      16
      1495
    6. Nesteen bensapumput pois, tilalle latausasemat

      Näin se maailma muuttuu, kun Suomessakin liikenneasemat lopettavat polttoaineiden myynnin ja tarjoavat enää sähköä autoi
      Maailman menoa
      178
      1402
    7. Mitä tämä tarkoittaa,

      että näkyy vain viimevuotisia? Kirjoitin muutama tunti sitten viestin, onko se häipynyt avaruuteen?
      Ikävä
      42
      1381
    8. Nukkumisiin sitten

      Käsittelen asiaa tavallani ja toiveissa on vielä että tästä pääsee hyppäämään ylitse. Kaikenlaisia tunteita on läpikäyny
      Ikävä
      4
      1357
    9. Syö kohtuudella niin et liho.

      Syömällä aina kohtuudella voi jopa laihtua.On paljon laihoja jotka ei harrasta yhtään liikuntaa. Laihuuden salaisuus on
      Laihdutus
      25
      1344
    10. Muistatko komeroinnin?

      Taannoin joskus kirjoitin aloituksen tänne komeroinnista eli hikikomoreista; syrjäytyneistä nuorista ihmisistä. Ehkä asu
      Suhteet
      51
      1287
    Aihe