练习题4.0.1

  1. 《码影忍者:乐程传》开端!禁术·多重影分身之术

/*在一个没有太阳的晚上,旋涡鸣堃从明理楼盗取了二代目码影的禁术卷轴,打开一看,竟然记录了失传已久的 批量复制粘贴CV之术!

“塔就克诶 本心 诺 几似!”

鸣堃发动禁术却难以驾驭,在场一共n个鸣堃难辨真假,却都说自己是真身。

鸣堃本体灵机一动,与众人达成约定:*/

从1到n给每人一个编号,然后首尾相连围成一圈,从编号为1的人从1开始依次报数,报到m的人被认为是分身然后清除掉,其后一个人继续从1开始报数...如此反复,直至场上只剩下一个鸣堃。

/*原来鸣堃本体一番计算发现如此运作后,剩下的一定是自己。*/

请问鸣堃真身的编号是?

(高仿题)原型约瑟夫环

输入格式:

一个整数n,一个整数m(m,n均不大于1000)

输出格式:

鸣堃的编号。

输入样例1:

11 3

输出样例1:

7

输入样例2:

10 3

输出样例2:

4

思路:成环,依次遍历数组,找到符合条件的就变为0,建议在纸上多跑两边

数组做法:(可能复杂化了,见谅)

#include<stdio.h>
int main()
{
	int n,m;
	scanf("%d %d",&n,&m);
	int x = n;
	int a = 1;
	int arr[1000] = {};
	for(int i = 1;i<n;i++)
	{
		arr[i] = i;
	}
	arr[0] = n;//伪环,后面是用j%n来判断替换元素的,扫到末尾对应值为0.
for(int j = 1; x!=1; j++)
{
	if(a != m%n&&arr[j%n]!= 0)//要跳过为0元素
	{
		a = a + 1;
	}
	else if(a == m%n&&arr[j%n] != 0)//m可能大于n,实际位移量是m%n
	{
		arr[j%n] = 0;
		a = 1;//重置计数游标
		x--;非0值剩余个数
	}
}
for(int k = 1;k<=n;k++)
{
	if(arr[k] !=  0)
	{
		printf("%d",arr[k]);
	}
}

	return 0;
 } 

找到了大佬的代码(谢谢大佬的素材): 

#include<iostream>
using namespace std;

int main()
{
//	初始化 
	int n, m;
	cin >> n >> m;
	int a[n];
//	把数组所有元素都初始化为1 
	for(int i = 0; i < n; i ++){
		a[i] = 1;
	}
//cnt是一个用于记录数数的变量,n2是n的拷贝 
	int cnt = 1, n2 = n;
	
	for(int i = 0; n2 > 1; i ++){
		if(cnt % m == 0 && a[i % n] == 1){
			n2 --;
			cnt ++; 
			a[i % n] = 0;
		}
		
		if(a[i % n] == 1){
			cnt ++;
		}
	}
	
	for(int i = 0; i < n; i ++)
		if(a[i] == 1)
			cout << "最终结果是" << i + 1 << endl;
	return 0;
}

3,链表做法:这个是循环链表,基操做就完事,bug细节还是很多的:

#include<stdio.h>
#include<stdlib.h>
typedef struct list
{
	int  data;
	struct list*next;
};

list*create()
{
	list*head = (list*)malloc(sizeof(int));
	if(head == NULL)
	{
		return NULL;
	}
	head->next = NULL;
	return head;
}
void push(list*head,int n)//插入数据 
{	
	list*pre = head;
	while(pre->next != NULL)
	{
		pre = pre->next;
	}
	list*cur = (list*)malloc(sizeof(int));
	cur->data = n;
	cur->next = NULL;
	pre->next = cur;
}
void pop(list*pre)//删除对应位置的数据,n是记录位置的数据 ,删除的是pre的下一号元素 
{
	pre->next = pre->next->next;
} 
/*void print(list*head)
{
	head = head->next;
	while(head != NULL)
	{
		int a = head->data;
		printf("%d",a);
		head = head->next;
	}
	
}打印链表,循环的就会一直打印*/
int main()
{	int n;
	scanf("%d",&n);
	int c = n;
	list*head = create();
for(int i = 1;i<=n;i++)//创建环形链表 ,并输入数据 
{
	push(head,i);
}
	list*pre = head;
while(pre->next != NULL)
{
	pre = pre->next;
}
	pre->next = head->next;//不是指向head!!!head我理解的只是起一个引子的作用
	int m;
	scanf("%d",&m);
list*he = head->next;
int b = 1;
while(c!= 1)
{
if((b + 1) % m != 0)
{
	he = he->next;
	b = b + 1;
} 
else
{
	pop(he);//删除符合条件的元素
	b = b + 1;
	c = c - 1;
}
}
	int d = he->data;
	printf("%d",d);
	return 0;
}

问题:最后的he->data能不能换成head->next?

不可以,因为从始至终没有修改过head的值,所有head->next也会是固定的。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值