标题:(类似于约瑟夫环问题的)熄灯问题
只看楼主
ClearningC
Rank: 2
等 级:论坛游民
帖 子:98
专家分:43
注 册:2016-10-26
结帖率:89.47%
已结贴  问题点数:10 回复次数:9 
(类似于约瑟夫环问题的)熄灯问题
假设围绕着一个圆形舞台有N个彩灯,编号从0到N-1,2<=N<=50,为了配合演出效果需要进行花式熄灯。熄灯的规则是从第x号灯开始熄灭,然后向编号更大的方向数,每逢y个亮着的灯后灭掉当前数到的亮着的彩灯,直到灭完为止。注意N-1号灯与0号灯互为邻居,数到N-1号灯,下一个为0号灯。
要求:
彩灯数量N,第一个灭灯的位置x,以及间隔y,使用空格间隔输入
灭灯的顺序,一行内输出,使用空格间隔,最后没有空格,全部输出完毕之后换行
例如:
Sample Input
10 2 3
Sample Output
2 5 8 1 6 0 7 4 9 3

(最后输出的“3”后面没有空格,但是有换行)
搜索更多相关主题的帖子: 约瑟夫 舞台 演出 
2016-11-28 15:33
ClearningC
Rank: 2
等 级:论坛游民
帖 子:98
专家分:43
注 册:2016-10-26
得分:0 
没有人吗?求帮助,我不知道怎么跳出循环呀
2016-11-28 20:15
groveer
Rank: 3Rank: 3
来 自:世界的一角
等 级:论坛游侠
威 望:1
帖 子:77
专家分:182
注 册:2013-11-18
得分:2 
程序代码:
#include<stdio.h>
#include<stdlib.h>

int main(void)
{
    int N,x,y;
    do
    {
        printf("请输入N(2<=N<=50) x y:\n");
        scanf("%d %d %d",&N,&x,&y);
        system("cls");
    }while(!(N>=2&&N<=50));
    for(;x<N;x++)
    {
        if(x%y==0)
            printf("%d ",x);
    }
    return 0;
}

付出不亚于任何人的努力~
2016-11-28 20:41
luoj75
Rank: 2
等 级:论坛游民
帖 子:17
专家分:55
注 册:2016-11-28
得分:2 
#include<stdio.h>
int main(void)
{
    int N=0,x,y,iaa,two=1;
    scanf("%d%d%d",&N,&x,&y);
    int a[N-1];
    for(iaa=0;iaa<=N-1;iaa++){
        a[iaa]=0;
    }
    for(iaa=0;iaa<=N-1;iaa++){
        printf("%d",x);
         a[x]=1;
          if(iaa!=N-1) printf(" ");
           if(iaa==N-1)
            {printf("\n");
            break;}
        for(two=1;two<=y;two++){
            x=x+1;
            if(x>N-1)
             x=x-N;
            if(a[x]==1)
             two--;
        }
    }
    return 0;
}
2016-11-28 20:46
ClearningC
Rank: 2
等 级:论坛游民
帖 子:98
专家分:43
注 册:2016-10-26
得分:0 
#include<stdio.h>
int main()
{
    int n,x,y,i,count,out;
    scanf("%d%d%d",&n,&x,&y);
    out=0;count=0;
    int light[n];
    for(i=0;i<n;i++)
        light[i]=0;
    printf("%d ",x);
    light[x]=1;
    for(i=x+1;i<n&&out!=n-2;i++)
    {
        if(light[i]==0)
        count++;
        if(count==y)
        {
            light[i]=1;
            printf("%d ",i);
            out++;
            count=0;
        }
        if(i==n-1)
        i=-1;
    }
    if(out==n-2)
    {
        for(i=0;i<n;i++)
        {
            if(light[i]==0)
            printf("%d\n",i);
        }
    }
    return 0;
}
我这里如果输入的是10 9 10的话,只能输出9
我知道是这里出错for(i=x+1;i<n&&out!=n-2;i++)
我想问一下,该怎么改?
2016-11-28 21:07
ClearningC
Rank: 2
等 级:论坛游民
帖 子:98
专家分:43
注 册:2016-10-26
得分:0 
回复 4楼 luoj75
我有想过用两个循环来解决,但是就是想不出你的这种循环的方法!
2016-11-28 21:09
九转星河
Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19
来 自:长长久久
等 级:贵宾
威 望:52
帖 子:5023
专家分:14003
注 册:2016-10-22
得分:2 
一个主循环就够了~

程序代码:
/*类约瑟夫环问题的数组解法*/

#include <stdio.h>

int main()    
{                                    //声明部分
    int N,x,y;                       //彩灯数量N,第一个灭灯的位置x,间隔y
    int i,j,a[50],num;    

    scanf("%d%d%d",&N,&x,&y);       //输入部分

    for(i=0;i<N;i++)          
        a[i]=i;                        //把每盏灯的编号赋值

    num=N;                          //初始化数据,用数组记录每盏灯的编号

    printf("%d ",x);                //处理第一个数据,即输出熄灭第一盏灯的位置
    num--;                          //剩余灯数-1
    a[x]=-1;                       //当被点灯时,记录编号的数据变为-1

    for (i=x,j=0;num;i++)           //i为点到灯的编号,j为记点次数,num剩余为灯数-每次执行循环点到灯的编号增加1
    {                               //当剩余灯数为0时结束循环
        if (i==N)                  //当点到灯的编号大于人数(等于N)时,编号重置为0
            i=0;

        if (a[i]==-1)              //当被点灯时,记录编号的数据变为-1,当再次被点时,跳过本次循环
            continue;

        j++;                       //经过continue筛选后,此时i已经点到下一位没有被筛选的灯的编号,记点次数加1

        if (j==y)                   //当记点次数与间隔的值相等时
        {
            printf("%d ",a[i]);    //输出此时对应的编号
            a[i]=-1;               //把编号标记为-1,表示此灯已被熄灭
            num--;                 //剩余灯的数量减少1
            j=0;                  //记点重置为0
        }

    }

    printf("\n");  
    return 0;
}



[此贴子已经被作者于2016-11-29 01:00编辑过]


[code]/*~个性签名:bug是什么意思?bug是看上去没有可能的东西实际上是有可能做到的 就是这样~2018-08-08更~*/[/code]
2016-11-29 00:57
吹水佬
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:版主
威 望:432
帖 子:10064
专家分:41463
注 册:2014-5-20
得分:2 
#include <stdio.h>
#include <string.h>
main()   
{
    char a[256];
    int N=10, x=2, y=3;
    int i;
   
    for (i=x; i<N; i++)
        a[i-x] = i;
    for (i=0; i<x; i++)
        a[N-x+i] = i;
    while (N>0)
    {
        printf("%d ", a[0]);
        memmove(a+N, a+1, y-1);
        memmove(a, a+y, N-1);
        N--;
    }
}
2016-11-29 11:42
rjsp
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:版主
威 望:507
帖 子:8890
专家分:53117
注 册:2011-1-18
得分:1 
程序代码:
#include <stdio.h>

int main( void )
{
    unsigned n, x, y;
    scanf( "%u%u%u", &n, &x, &y );

    unsigned char buf[50] = { 0 };
    for( unsigned i=0, count=y-1; i!=n; x=(x+1)%n )
    {
        if( buf[x] == 0 )
            ++count;

        if( count == y )
        {
            printf( "%u ", x );
            buf[x] = 1;
            count = 0;
            ++i;
        }
    }

    return 0;
}
2016-11-29 12:29
yangfrancis
Rank: 16Rank: 16Rank: 16Rank: 16
等 级:贵宾
威 望:141
帖 子:1510
专家分:7661
注 册:2014-5-19
得分:1 
#include<stdio.h>
void Joseph(int total,/*总数N*/int count,/*要数的数y*/int start/*起始位置x*/)
{
    int i;/*循环索引*/int n;/*熄灯个数记录*/
    int*flag=(int*)malloc(sizeof(int)*total);
    for(i=0;i<total;i++) flag[i]=0;
    printf("熄掉第%d个\n",start);
    flag[--start]=1;n=1;
    while(n!=total)
    {
        i=0;
        while(i!=count)
        {
            start=(start==total-1)?0:start+1;
            if(flag[start]==0)
            {
                i++;
            }
        }
        printf("熄掉第%d个\n",start+1);
        flag[start]=1;n++;
    }
}
int main()
{
    Joseph(10,3,1);
    return 0;
}
2016-11-29 21:16



参与讨论请移步原网站贴子:https://bbs.bccn.net/thread-471704-1-1.html




关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.022744 second(s), 7 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved