cppAcademy
FROM LEARNING TO COMPETING

Proficient.
Put your skills to the test.

Bulgarian Informatics Group B · 2009–2026

217 independently explained problems: 54 Municipal, 54 Regional and 109 National. Start with the easier tasks and work upwards. Difficulty labels are learning estimates, not official ratings; Group B also includes challenging national-level problems. National-round tasks shared by Groups A and B are included. Years follow Arena’s competition-season labels. Source clarifications and special grader requirements are noted on affected tasks.
GROUP B2009 · EasyPrime numbers

Fatal Answer Algorithm

National Olympiad — Municipal round (2009 season)

Submission name: fatal.cpp

Problem summary

Given the correct answers to a multiple choice test, find the smallest positive M<1000 maximizing the score of this rule. Start each question at the first prime p at least M for the first question, or strictly greater than the previous stopping number later. Label p with a, then successive integers with b,c,d,a,... Stop at the first multiple of 13 and select the following letter.

Input

n, followed by a string of n letters from a,b,c,d.

Output

The smallest M giving the highest number of correct answers.

Constraints

1 ≤ n ≤ 50; 1 ≤ M < 1000.

Worked example

An independently prepared example for this explanation.

Input

2
ac

Output

1

Solution analysis

  1. Try every permitted M in increasing order. For each question find the next prime by trial division; then compute the stopping multiple as 13 times the ceiling of p/13.
  2. If the stopping multiple is t, its letter has index (t−p) modulo 4. The selected next letter therefore has index (t−p+1) modulo 4. Start the next prime search at t+1.
  3. For M=1 the first prime is 2 and the stop is 13, producing a. The next prime is 17 and the stop is 26, producing c. Both answers match the sample.

Why it works

The computed t is exactly the first permitted multiple of 13. The modular formula counts exactly the letter increments including the final advance. Therefore every simulated score is correct; exhaustive increasing enumeration with strict score improvement returns the smallest maximizer.

Complexity: O(1000·n·g·√P) time, where P is the largest searched number and g the largest prime-search gap; O(1) auxiliary space excluding the input string. Here P is only a few thousand.

Watch out. 1 is not prime. Select the letter after the stopping letter, and begin the next prime search strictly after the stopping number.

Commented C++17 solution

An independently written complete program with standard headers.

#include<iostream>
#include<string>
using namespace std;
bool prime(int value){
    if(value<2){
        return false;
    }
    for(int d=2;d*d<=value;d++){
        if(value%d==0){
            return false;
        }
    }
    return true;
}
int main(){
    // Compute the exact archive answer using the method explained above.
    int n;
    string correct;
    cin>>n>>correct;
    int best=-1;
    int answer=1;
    for(int start=1;start<1000;start++){
        int p=start;
        int score=0;
        for(int question=0;question<n;question++){
            while(!prime(p)){
                p++;
            }
            int stop=((p+12)/13)*13;
            char chosen=static_cast<char>('a'+(stop-p+1)%4);
            score+=chosen==correct[question];
            p=stop+1;
        }
        if(score>best){
            best=score;
            answer=start;
        }
    }
    cout<<answer<<'\n';
}

Source: Arena Olimpiici ↗