前段时间Q群里有提问如下,编写程序解决一个学生按规则依次报数的体育游戏问题。编程语言不限,Java, C#, Ruby, C++, Js, Python, Scala, objective-C统统可以,小语种也没问题。

一、问题描述:
你是一名体育老师,在某次课距离下课还有五分钟时,你决定搞一个游戏。此时有100名学生在上课。游戏的规则是:
1. 你首先说出三个不同的特殊数,要求必须是个位数,比如3、5、7。
2. 让所有学生拍成一队,然后按顺序报数。
3. 学生报数时,如果所报数字是第一个特殊数(3)的倍数,那么不能说该数字,而要说Fizz;如果所报数字是第二个特殊数(5)的倍数,那么要说Buzz;如果所报数字是第三个特殊数(7)的倍数,那么要说Whizz。
4. 学生报数时,如果所报数字同时是两个特殊数的倍数情况下,也要特殊处理,比如第一个特殊数和第二个特殊数的倍数,那么不能说该数字,而是要说FizzBuzz, 以此类推。如果同时是三个特殊数的倍数,那么要说FizzBuzzWhizz。
5. 学生报数时,如果所报数字包含了第一个特殊数,那么也不能说该数字,而是要说相应的单词,比如本例中第一个特殊数是3,那么要报13的同学应该说Fizz。如果数字中包含了第一个特殊数,那么忽略规则3和规则4,比如要报35的同学只报Fizz,不报BuzzWhizz。
现在,我们需要你完成一个程序来模拟这个游戏,它首先接受3个特殊数,然后输出100名学生应该报数的数或单词。比如,
输入
3,5,7
输出(片段)
1
2
Fizz
4
Buzz
Fizz
Whizz
8
Fizz
Buzz
11
Fizz
Fizz
Whizz
FizzBuzz
16
17
Fizz
19
Buzz
…
一直到100二、解决方法:
这个问题主要是要理解提到的游戏规则,然后为每个学生对应的序号匹配出对应的rule模式,这样问题就解决了。下面是自己用C写的解决方法:
main.c
/**
* 游戏体育老师写3个个位数,100名同学按一定规则报数的问题
* @filename: game.c
* @author : vfhky 2014.10.25 https://typecodes.com
*/
#include "stdio.h"
#include "string.h"
#define TotalNum 100
/**
* 获取一个1000范围内的整形数据的各个位
* @param [in] number 学生序号
* @param [in/out] highnum 将每个位依次保存到数组
* return 0: 成功; -1:整数超出范围
*/
int gethighnum( int number, char highnum[] )
{
if( number < 10 )
{
*highnum = number + 48;
return 1;
}
else if( number < 100 )
{
*highnum = number/10 + 48;
*(highnum+1) = number%10 + 48;
return 1;
}
else if( number < 1000 )
{
*highnum = number/100 + 48;
*(highnum+1) = ( number - (number/100)*100 )/10 + 48;
*(highnum+2) = number%100 + 48;
return 1;
}
else
return -1;
}
/**
* 将学生序号按照规则3/4/5处理: 最后匹配出对应的字符串
* @param [in] inputa 老师输入的第一个数字
* @param [in] inputb 老师输入的第二个数字
* @param [in] inputc 老师输入的第三个数字
* @param [in] number 学生序号
* @param [in/out] matchstr 匹配的字符串
* @param [in/out] flag 是否包含了匹配数字, 0:未包含 1: 包含
* return -1: 该学生序号不合法; 0:未包含第一个数字; 1:包含第一个数字;
*/
int rules( int inputa, int inputb, int inputc, int number, char matchstr[], int * flag )
{
int result;
char highnum[4] = { 0 }; //整数的各个位
*flag = 0;
result = gethighnum( number, highnum ); //获取该整数的所有高位字符highnum
if( result != 1 )
return -1;
/* 检测是否包含第一个特殊数字 */
for( result=0; result<strlen(highnum); result++ )
{
if( inputa == highnum[result] - 48 )
return 1;
}
memset( matchstr, 0x30, 4 );
if( number % inputa == 0 )
{
*matchstr = 0x31;
*flag = 1;
}
if( number % inputb == 0 )
{
*(matchstr+1) = 0x32;
*flag = 1;
}
if( number % inputc == 0 )
{
*(matchstr+2) = 0x33;
*flag = 1;
}
return 0;
}
int main( int argc, char * argv[] )
{
int stuinx = 1; //学生序号, 从1开始报数
int a, b, c; //老师输入的三个整型数据
int result; //临时数据
/* 初始化对应的三个字符串数据 */
char arr1[5] = "Fizz";
char arr2[5] = "Buzz";
char arr3[6] = "Whizz";
char arr[14];
/* 老师输入3个整形数据 */
printf( "Please input three integer number:\n eg. 3, 5, 7\n" );
scanf( "%d, %d, %d", &a, &b, &c );
if( a>0xa || b>0xa || c>0xa )
{
printf( "You should inpute three integer number!\n" );
return -1;
}
printf( "You have inputed three integer number:[%d], [%d], [%d]\n", a, b, c );
int flag, *p;
p = &flag;
char matchstr[4] = { 0 };
/* 学生开始依次报数 */
for( ; stuinx<TotalNum+1; stuinx++ )
{
/* 每次循环重新初始化数据 */
flag = 0;
memset( arr, 0x00, sizeof(arr) );
memset( matchstr, 0x30, sizeof(matchstr) );
/* 根据规则获取匹配字符串matchnum以及是否包含匹配字符的标志*p */
result = rules( a, b, c, stuinx, matchstr, p );
if( result == -1 )
printf( "The total number of students can not be more than 1000!\n" );
else if( result )
{
strcpy( arr, arr1 );
printf( "No.[%d] says [%s]\n", stuinx, arr );
continue;
}
if( *p )
{
/* 如果包含了非第一个特殊数字 */
for( result=0; result<strlen(matchstr); result++ )
{
if( matchstr[result] == 0x31 )
strcat( arr, arr1 );
else if( matchstr[result] == 0x32 )
strcat( arr, arr2 );
else if( matchstr[result] == 0x33 )
strcat( arr, arr3 );
}
printf( "No.[%d] says [%s]\n", stuinx, arr );
}
else
printf( "No.[%d] says [%d]\n", stuinx, stuinx );
}
return 0;
}三、测试结果
GCC编译后执行,结果如下图所示。但发现没有任何一位学生在报数时,需要报包含Fizz、Buzz、Whizz全部这三个单词的组合,例如不会出现题目规则4中所述的FizzBuzzWhizz。原因可以直接从前面的几条规则中推导出来。

评论
评论加载中…