[题解]无厘头题目——无聊的军官

这道题非常无厘头!

题目描述:

每个学年的开始,高一新生们都要进行传统的军训。今年有一个军训教官十分奇怪,他为了测试学员们的反应能力,每次吹哨后学员们都会变换位置。每次左数第I位学员都会站到第ai个位置,经过若干次之后,队伍又会回到原来的样子。你的任务是计算n个人的队伍至少经过多少次之后,队伍恢复到原来样子。

输入格式:

输入文件的第一位包含一个整数N(0<N10000),表示队伍的人数。
接下来N行,每行一个正整数ai表示左起第i个人接下来出现在左起第ai个位置上。

输出格式

仅包括一行,一个正整数M,表示军官最少的吹哨次数。

样例:

输入:

5

2 3 4 5 1

输出:

5

分析:

这道题大家一拿上就会想到模拟。

那么我们用模拟做一下。

#include<bits/stdc++.h>   //我总算掌握万能头文件了 
using namespace std;
int main()
{
	int n,i,j,o[105],l[105],t[105],flag=0,sum=0,u[105];   //定义所需数组 
	cin>>n;   
	for(i=1;i<=n;i++)   //初始化数组 
	{
		o[i]=i;
		t[i]=i;
		u[i]=i;
	}
	for(i=1;i<=n;i++)   //输入变化规律 
	{
		cin>>l[i];
	}
	while(1)    //不知道什么时候结束就用这个 
	{
		for(i=1;i<=n;i++)   //变化 
		{
			o[l[i]]=t[i];
		}
		sum++;   //记录变化次数 
		flag=0;    //用于标记是否与原数组相等 
		for(i=1;i<=n;i++)
		{
			if(o[i]!=u[i])   //如果与原数组不相等 
			{        
				flag++;   //标记 
			}
		}
		if(flag==0)   //没有标记就是与原数组相等 
		{
			cout<<sum;
			exit(0);   //强力结束! 
		}
		for(i=1;i<=n;i++)   //及时更新 
		{
			t[i]=o[i];
		}
	}
}

当你看到样例过了兴冲冲的提交才发现——————

这么写只能得30分!

(此时的精神状态)

这道题的满分做法是找环再求最小公倍数。

我们仔细观察一下。

我们可以发现:1,2成一个环,3,4,5成一个环。

然后我们把几个环的长度求最小公倍数即可。

#include<bits/stdc++.h>    //万能头用上瘾 
using namespace std;
int a[100005],o[1000005],w,sum,flag[1000005],b[100005],cnt,gbsh,gys;  //好多啊 
int main()
{
	int i,sum=0,n,j;   //这还有几个 
	cin>>n; 
	for(i=1;i<=n;i++)   //输入 
	{
		cin>>a[i];
	}
	for(i=1;i<=n;i++)   //核心 
	{
		if(flag[i]==0)    //如果没有标记 说明还没有成环 
		{
			w=i;   //w记录当前位置 
			sum=1;    //第一个位置也算所以初始值是1 
			flag[w]=1;    //当前位置必须标记! 
			while(1)    //熟悉配方 
			{
				if(flag[a[w]]==0)    //如果下一个位置没有标记 
				{
					sum++;    //环的长度 
					flag[a[w]]=1;    //下一个位置必须标记! 
				}
				else
				{
					break;    //已经有环了跳过 
				}
				w=a[w];   //当前位置更新! 
			}
			cnt++;   //环的个数 
			b[cnt]=sum;   //记录环的长度 
		}
	}
	//求最小公倍数 
	for(i=1;i<cnt;i++)   //有可能会超出所以是 <cnt 
	{
		//先求最大公因数 
		for(j=max(b[i],b[i+1]);j>=1;j--)
		{
			if(b[i]%j==0&&b[i+1]%j==0)
			{
				gys=j;
			}
		}
		gbsh=b[i]*b[i+1]/gys;   //求A与B的最小公倍数方法:A*B÷C   (C表示两数的最大公因数) 
	}
	cout<<gbsh<<endl;   //这才是最终答案
	return 0;   //潇洒结束 
}

求最大公因数和最小公倍数有种算法叫欧几里得算法,等到学了一定会给大家及时更新!

感谢阅览!欢迎一键三连!欢迎订阅专栏!Thanks♪(・ω・)ノ

  • 11
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值