任务:编号为1——52的纸牌,正面向上,从第2张开始,以2为基数,是2的倍数的牌翻一次,直到最后一张牌。然后从第3张开始,以3为基数,是3的倍数的翻一次,直到最后一张牌,然后再依次4的倍数的牌翻一次,5的、6的.....直到以52为基数的翻过,输出这是正面向上的牌有那些。
int card[53];
for(int k = 1; k<=52; k++)
card[k] = 0; //0表示正面向上.
for(int i = 2; i <= 52; i++)
{
for(int j = i; j <= 52; j += i)
card[k] = 1 - card[k]; //翻转一次.
}
也可以这样,借用楼上的代码
int card[52];
for(int k = 1; k<53; k++) //初始化牌面
card[k-1] = 1; //1表示正面向上,-1表示正面向下
//翻牌
for(int i = 1; i < 53; i++)
{
for(int j = i; j < 53; j += i)
card[k-1] *= -1; //翻转一次.
}
//输出结果
for(int i = 1; i < 53; i++)
{
if (card[k-1] == 1)
cout << "第" << k << "张牌正面向上" << endl;
}
实际上从数学上就可以知道是哪些数正面朝上。
首先分析一下,点数为N的牌在什么情况下被翻。
由楼主描述的算法可知,当某一轮的基数B为N的约数时,N将被翻转一次。
其次分析一下,点数为N的牌有多少次翻转机会。
点数为N的牌,假设N的约数个数为X个,那么当基数B从2到无穷的变化过程中,N将被翻转X-1次,因为基数是从2开始的,约数1将被排除在外。
第三分析一下,点数为N的牌怎么样才能是最后正面向上的。
明显,当被翻转的次数 X-1 是偶数时,将正面向上。
最后分析,什么样的数才能使X-1是偶数
X-1是偶数,意味着X是奇数。
我们知道,正常情况下,约数是成对出现的,
比如12的约数有1,12; 2,6; 3,4;共有三对6个
而只有完全平方数才会有两个约数相等,这样才有奇数个约数
所以最后输出的结果必是完全平方数:1,4,9,16,25,36,49
若要将此游戏推广下去,如扑克的张数由52增加到108,那么输出结果将多出一个81.