C/C++——猴子选大王(PTA)

超详注释! 包你一秒钟都看不懂!

2022-7-13更新:

昨天做力扣的#27移除元素,学会了双指针法,今天突然想起这道题,发现可以参考参考双指针。

附上题目:

本关任务:编写一个函数 ki ng,实现猴子选大王的功能。

新猴王的选择方法是:让 n 只候选猴子围成一圈(最多100只猴子),从某位置起顺序编号为 1 ~ n 号。从第1号开始报数,每轮从1报到3,凡报到3的猴子即退出圈子,接着又从紧邻的下一只猴子开始同样的报数。如此不断循环,最后剩下的一只猴子就选为猴王。

测试输入:5
预期输出:4

测试输入:18

预期输出:14

注意:
1.题目要求猴子们按照123123..报数,等效于123456..n中,3的倍数被淘汰
2.可根据题目要求报3,报5,报n,等等自行对淘汰条件,以及count的重置进行更改

using namespace std;
#include

int main () {
	//一: 初始化。     猴子数组存储其对应下标
	//注意,猴子从1报数,闲置Monkey[0] ,从Monkey[1]开始存储
	int Monkey[100],n;
	cout<<"请输入猴子数目:";
	cin>>n;
	for(int i=1; i<=n; i++) {
		Monkey[i]=i;//存储对应下标
	}

	//二,开始报数以及淘汰。  参考双指针法变形 (多了一个报数而已)
	int count=0,slow;//注意count定义为1  或 定义为0 ,对后续有一定影响
	while(n!=1) {
		//第一步,for循环遍历所有健在猴子,进行一轮淘汰
		slow=0;//慢指针更新数组,每次循环前重置
		for(int i=1; i<=n; i++) {//  n在while每轮结束时更新
			count++;
			if( (count)%3!=0 ) {
				slow++;
				Monkey[slow]=Monkey[i];//淘汰的猴子直接被未淘汰猴子覆盖
			}
		}

		//第二步,重置count ,下一轮第一个猴子,接着上一轮最后一只猴子的报数
		if(count%3==1) {
			count=1;
		} else if(count%3==2) {
			count=2;
		} else if(count%3==0) {
			count=0;
		}
		n=slow;
	}
	cout<<"猴王是:"<

忘了以前的题目要求,这里我认真敷衍几句输出文字,大家可根据题目要求更改


2021-12-13:经过东平西凑,到处借鉴大家的优秀成果,终于做完了。(以下是运行成功的代码)

#include 

int main()
{
    int monkey[1000], N;
    scanf("%d", &N);//N表示输入猴子的数目

    for (int i = 0; i <= N; i++)
    {
        monkey[i] = 1;//给这N个猴子赋值为1,表示在圈内,参与报数
    }

    //问题:谁报1,第一只猴子,报1,但其数组下标为0.
    int count = 0, n = 0, t = 0, king = 0;//count报数,n淘汰猴子数,t留存猴子数,king留着记猴王下标

    while (t != 1)//只剩一只猴子则结束游戏
    {
        if (N == 1) { break; };//啊啊啊啊阿这才是最后的关键所在!!!!!!从循环中跳出来哈哈哈哈
        for (int i = 0; i < N; i++)//这仅仅是一次淘汰(现在是第一次),第二次呢
        {
            if (monkey[i] == 1)//每轮只有在圈内的“1”猴子才能参与游戏
            {
                count++;//问题是count报3,谁才是被淘汰的,即找淘汰猴子与下标i的关系
                if (count % 3 == 0)
                {
                    {
                        monkey[i] = 0; //报数报到3和3的倍数的猴子重置为0,即淘汰
                        n++;//记录被淘汰猴子数目,留着当n=N-1(只剩一只猴子)时作为游戏结束标志
                        t = N - n;//t是留存猴子 个数  
                    }
                }
            }
        }

        if (count % 3 == 0)//一轮结束后,最后被淘汰位置的后面留存猴子(X复杂思想)
        {
            count = 0;
        }
        else if (count % 3 == 1)//哈哈哈我还用monkey[pleace+1],这里直接用报数与3的关系重新调整开头的报数
        {
            count = 1;
        }
        else if (count % 3 == 2)
        {
            count = 2;
        }
    }

    for (int i = 0; i <= N; i++)
    {
        if (monkey[i] == 1)//遍历数组,找到最后一个“1”猴子下标
        {
            king = i + 1; break;//(咦,好像不用执着于记录淘汰猴子来查出猴王,直接找最后剩为1,的猴子数组下标+1就OK了)
        }
    }
    printf("%d", king);
}

2.解决途中看到了C语言的函数解法,忘了是哪位大神了,我还是留着慢慢看,以后再来重新优化我的解法吧(以下是部分当时截取的代码):

int N, arr[1001];//N猴子数
//返回函数
int succ(int t)//循环数组,使末尾报1,开头报2
{
	if (t == N)
	{	return 1;	}

	else//(t!=N)
	{	return t + 1;	}
}

int next_in_M(int t)
{
	int i;
	i = succ(t);
	while(a[i]!=1)
	{	i = succ(i);	}

	return i;
}

你可能感兴趣的:(PTA,c语言,后端,开发语言)