蓝桥杯算法训练之筛选号码(重点)

问题描述

有n个人围成一圈,顺序排号(编号为1到n)。从第1个人开始报数(从1到3报数),凡报到3的人退出圈子。从下一个人开始继续报数,直到剩下最后一个人,游戏结束。
  问最后留下的是原来第几号的那位。
  举个例子,8个人围成一圈:
  1 2 3 4 5 6 7 8
  第1次报数之后,3退出,剩下:
  1 2 4 5 6 7 8 (现在从4开始报数)
  第2次报数之后,6退出,剩下:
  1 2 4 5 7 8 (现在从7开始报数)
  第3次报数之后,1退出,剩下:
  2 4 5 7 8 (现在从2开始报数)
  第4次报数之后,5退出,剩下:
  2 4 7 8 (现在从7开始报数)
  第5次报数之后,2退出,剩下:
  4 7 8 (现在从4开始报数)
  第6次报数之后,8退出,剩下:
  4 7 (现在从4开始报数)
  最后一次报数之后,4退出,剩下:
  7.
  所以,最后留下来的人编号是7。
  
输入格式

一个正整数n,(1<n<10000)
  
输出格式

一个正整数,最后留下来的那个人的编号。
  
样例输入

8

样例输出

7

数据规模和约定

对于100%的数据,1<n<10000。

我写的代码如下:
(迄今为止遇到最复杂的题目,很像约瑟夫问题)

#include<stdio.h>
int main()
{
	char str[10001];
	int n,i,count=1;
	int j,x,m=0;
	scanf("%d",&n);
	for (i = 0; i < n; i++)
	{
			str[i] = 0;
	}
	while (count!=n)
	{
		for (j = 0; j < n; j++)
		{
			if (str[j] == 0)
			{
				m++;
			}
			if (m == 3)
			{
				str[j] = 1;
				m = 0;
				count++;
			}
		}
	}
	for (x= 0; x < n; x++)
	{
		if (str[x]==0)
		{
			printf("%d",x+1);
		}
	}
	return 0;
}

解题思路:

创建一个数组来代表一队人,用数组的赋值0或1来表示是否被选中,用循环来实现选择,其中循环的判定条件要讲一下,通过对题目的分析可以发现不管n是多少都只要选择 n-1次就可以找到剩下的那个数。

别人的代码:

#include <stdio.h>   
 #include <malloc.h>   
 typedef struct form{   
     int num;   
     int date;   
     struct form *link;}   
 del;   
 del *creat(int n){   
 int i;   
 del *head,*p1,*p2;   
 head=(del *)malloc(sizeof(del));   
 p1=(del *)malloc(sizeof(del));   
 head->link=p1;   
 for(i=1;i<=n-2;i++){p2=(del *)malloc(sizeof(del));   
 p1->link=p2;   
 p1=p2;}   
 p1->link=head;   
 return(head);   
 }   
 void dateop(del *h,int n){   
     del *p;   
     int i,j=1;   
     p=h;   
     for(i=1;i<=n;i++){   
     p->num=i;   
     p->date=j;j++;   
     if(j==4) j=1;   
     p=p->link;}   
 }   
 int deal(del *h,int n){   
     del *k;   
     int s;   
     int count,j=1,i;   
     count=n;   
     k=h;   
     while(count!=1){   
     if(j==3&&k->date!=0) {k->date=0;count--;}   
 k=k->link;   
     j++;   
     if(k->date==0) j--;   
 if(j==4) j=1;   
     }   
     k=h;   
     for(i=1;i<=n;i++){   
     if(k->date!=0) {s=k->num;break;}   
     k=k->link;}   
     return(s);}   
 int main(){   
     int x;   
     int i;   
     del *p;   
     scanf("%d",&x);   
     p=creat(x);   
     dateop(p,x);   
     x=deal(p,x);   
     for(i=1;i<x;i++){   
     p=p->link;}   
     printf("%d",p->num);   
 return 0;   
 }

很复杂,运用数据结构中的单链表和指针。

上一篇:js动态修改浏览器ico图标


下一篇:OSPF广播型网络如何计算路由?它独有的LSA 2包含什么信息?