Copyright (C) IOI日本委員会 1994. All rights reserved.


問題4.

正の整数で、桁を逆順に書いても元の数と同じになる数のことを回数と呼ぼう。 例えば、151や7337は回数である。素数であると同時に回数であるものを素回数と 呼ぶことにする。

以下の3つの異なる言語で書かれたプログラムは、 どれも min(=101) 以上 max(=1994) 以下の素回数の個数を出力する。 選択した言語について、空欄の部分を埋めよ。 空欄には一つの条件式(論理式)が入る。 [2点]


Cプログラム(4)


#include <stdio.h>
#include <math.h>
#define MIN      101
#define MAX     1994
#define KETA       4
#define DELETED    1
#define TRUE       1
#define FALSE      0

int sieve[MAX+1];
void Eratosthenes(void);
void print_palindromes(int, int);

main()
{
    Eratosthenes();
    print_palindromes(MIN,MAX);
    exit(0);
}

void Eratosthenes() /* MIN〜MAXの数について素数か否か計算 */
{  
    int i,n,k,sqrt_of_MAX;

    for (i=2; i<=MAX; i++)  
        sieve[i] = i;
    for (i=4; i<=MAX; i+=2) 
        sieve[i] = DELETED;
    n = 3; 
    sqrt_of_MAX = (int)sqrt((double)(MAX+1));
    do {
        if  (sieve[n] != DELETED)        
            for (i=n, k=MAX/n; i<=k; i++)
                 sieve[n*i] = DELETED;
    } while ((n+=2) <= sqrt_of_MAX);
}


int palindrome(int n) /* nが回数かどうか判定する */
{
    int k,keta,place[KETA];

    for (keta=0; n>0; n/=10)
        place[keta++] = n%10;
    for (k=0; k<=keta/2; k++)
              ------------------------------
        if ( |          空欄箇所            | )
              ------------------------------
            return FALSE;
    return TRUE;
}

void print_palindromes(int min, int max)
{
    int count,i;

    for (count=0, i=min; i<=max; i++)
        if (sieve[i]!=DELETED && palindrome(sieve[i])) 
            ++count;
    printf("\n総数は%d個です。\n", count);
}


QuickBASICプログラム(4)


DEFINT A-z
DECLARE SUB Eratosthenes()
DECLARE SUB printPalindromes(m,n)
DECLARE FUNCTION palindrome(n)

CONST min=101, max=1994, deleted=-1, maxKeta=4
DIM SHARED sieve(max) AS INTEGER

    CALL Eratosthenes
    CALL printPalindromes(min,max)
END

SUB Eratosthenes  'min〜maxの数について素数か否か計算
    FOR i=2 TO max: sieve(i)=i: NEXT i
    FOR i=4 TO max STEP 2: sieve(i)=deleted: NEXT i
    n=3: sqrtOFmax=SQR(max+1)
    DO
        IF sieve(n)<>deleted THEN
            FOR i=n TO max\n: sieve(n*i)=deleted: NEXT i
        END IF
        n=n+2
    LOOP WHILE n<=sqrtOFmax
END SUB


FUNCTION palindrome(n)  'nが回数かどうか判定する
    DIM place(maxKeta) AS INTEGER

    keta=0
    WHILE n>0
        keta=keta+1: place(keta)=n MOD 10: n=n\10
    WEND
    palindrome=-1
    FOR k=1 TO keta\2
            ------------------------
        IF |        空欄箇所        |  THEN palindrome=0
            ------------------------
    NEXT k
END FUNCTION


SUB printPalindromes(m,n) 
    count=0
    FOR i=m TO n
        IF (sieve[i]<>deleted) AND palindrome(sieve(i)) THEN count=count+1
    NEXT i
    PRINT: PRINT "総数は";count;"個です。"
END SUB


Pascalプログラム(4)


PROGRAM test4;
CONST min     = 101;
      max     = 1994;
      deleted = 1;
      maxKeta = 4;
VAR sieve : ARRAY[2..max] OF integer;

PROCEDURE Eratosthenes; { min〜maxの数について素数か否か計算 }
VAR i,n,sqrt_of_max : integer;
BEGIN
    FOR i:=2 TO max DO sieve[i]:=i;
    i:=4;
    WHILE i<=max DO
    BEGIN
        sieve[i]:=deleted;
        i:=i+2
    END;
    sqrt_of_max:=round(sqrt(max));
    n:=3;
    REPEAT
        IF sieve[n]<>deleted THEN
            FOR i:=n TO max DIV n DO sieve[n*i]:=deleted;
        n:=n+2
    UNTIL n>sqrt_of_max
END;

FUNCTION palindrome(n:integer): Boolean; { nが回数かどうか判定する }
VAR k,keta : integer;
    place : ARRAY[1..maxKeta] OF integer;
BEGIN
    keta:=0;
    WHILE n>0 DO
    BEGIN
        keta:=keta+1; place[keta]:=n MOD 10;
        n:=n DIV 10
    END;
    palindrome:=true;
    FOR k:=1 TO keta DIV 2 DO
            ---------------------
        IF |        空欄箇所     |  THEN palindrome:=false
            ---------------------
END;

PROCEDURE print_palindromes(m,n:integer);
VAR count,i : integer;
BEGIN
    count:=0;
    FOR i:=m TO n DO
        IF (sieve[i]<>deleted) AND palindrome(sieve[i]) THEN count:=count+1;
    writeln; 
    writeln('総数は',count,'個です。')
END;

BEGIN
    Eratosthenes;
    print_palindromes(min,max)
END.


JOI'94へ戻る

JOIホームページへ戻る