The Problem
During the power crisis in New Zealand this winter (caused by a shortage of rain and hence low levels in the hydro dams), a contingency scheme was developed to turn off the power to areas of the country in a systematic, totally fair, manner. The country was divided up into N regions (Auckland was region number 1, and Wellington number13). A number,m, would be picked `at random', and the power would first be turned off in region 1 (clearly the fairest starting point)and then in every m'th region after that, wrapping around to 1 after N, and ignoring regions already turned off. For example, ifN = 17 and m = 5, power would be turned off to the regions in the order:1,6,11,16,5,12,2,9,17,10,4,15,14,3,8,13,7.
The problem is that it is clearly fairest to turn off Wellington last(after all, that is where the Electricity headquarters are), so for a givenN, the `random' number m needs to be carefully chosen so that region 13 is the last region selected.
Write a program that will read in the number of regions and then determine the smallest number m that will ensure that Wellington(region 13) can function while the rest of the country is blacked out.
Input and Output
Input will consist of a series of lines, each line containing the number of regions (N) with . The file will be terminated by a line consisting of a single 0.
Output will consist of a series of lines, one for each line of the input. Each line will consist of the number m according to the above scheme.
Sample input
17 0
Sample output
7
Analysis
This is a typical Josephus problem. Since the input size is small, I don't use any advanced data structure but only a brute force approach. I know that my program is not good enough, so please give me suggestions to improve it!
/*
Uva OJ 151. Power Crisis
23th July 2014
GNU g++ @Fedora
*/
#include <iostream>
using namespace std;
int main()
{
int N; // Number of regions, 13<=N<=100
int M;
int visited; // step < m
bool region[101];
int pick;
int counter;
bool isWellingtonLast;
const int wellington = 12; // 13-1
cin >> N;
while( N!= 0 )
{
N--; // the first region is always chosen first
isWellingtonLast = false;
// try until Wellington is the last
for( int m=1; m<=N && !isWellingtonLast ; m++ )
{
for( int i=1; i<=N; i++ )
{
region[i] = false;
}
pick = 1; // index of region to be looked at
counter = N;
visited=0;
while( counter>0 )
{
if( pick > N ) pick%=N; // cannot exceed N
if( !region[pick] ) // visit those who haven't been turned off yet
{
visited++; // update number of regions visited
if( visited==m )
{
visited = 0; // clear visited, count again
region[pick] = true;
counter--;
if( counter==0 && pick==wellington ) // check whether the last region is 13
{
isWellingtonLast = true;
M = m;
}
}
}
pick++; // look at next region
}
}
cout << M << endl;
cin >> N;
}
return 0;
}