- 《码影忍者:乐程传》开端!禁术·多重影分身之术
/*在一个没有太阳的晚上,旋涡鸣堃从明理楼盗取了二代目码影的禁术卷轴,打开一看,竟然记录了失传已久的 批量复制粘贴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也会是固定的。