首页 新闻 会员 周边 捐助

一个问题,问下大佬们

0
[已解决问题] 解决于 2018-03-24 14:20

题目描述

节目主持人准备从n名学生中挑选一名幸运观众,因为大家都想争当幸运观众,老师只好采取这样的办法:全体同学排成一列,由前面往后面依顺序报数1,2,1,2,……,报单数的同学退出队伍,余下的同学向前靠拢后再重新由前往后1,2,1,2,……报数,报单数者退出队伍,如此下去最后剩下一人为幸运观众。编程找出幸运观众在原队列中站在什么位置上?

输入

仅一个整数n(n≤10000)。

输出

仅一个整数,表示幸运观众在原队列中站的位置。

样例输入

5

样例输出

4

时间限制: 1 Sec  内存限制: 128 MB)

请大佬给出题目的思路,最好能给出主要代码,谢谢!
c
Aehnuwx的主页 Aehnuwx | 菜鸟二级 | 园豆:263
提问于:2018-03-23 22:16
< >
分享
最佳答案
0

你等我,我来!

 

这个其实很简单,是一道规律题,找规律就能发现,其实这个题目的答案就是小于n的最大的2^m的数字。

我们可以先一段暴力的程序,(当然这个规律我在纸上找到的)

#include <iostream>
#include <stdio.h>
#include <string.h>
#include <string>

using namespace std;

int n;
int a[10005];
int main()
{
    scanf("%d",&n);
    for(int i=0;i<n;i++)
    {
        a[i]=(i&1?0:1);
    }
    int ans=0;
    while(true)
    {
        int x=1;
        int tag=0;
        for(int i=0;i<n;i++)
        {
            if(a[i]==0)
            {
                if(x==1)
                {a[i]=1;x=0;}
                else
                    x=1;
                
                tag++;
                ans=i;
                 
            }
           
        }
        if(tag==1)
            break;
        
    }
    printf("%d",ans+1);
    return 0;
   
}

这个程序显然是超时的,但是我们输入数据发现

8   ---  8

17 --- 16

5 ---- 4

267 --- 256

129 --- 128 

130 --- 128

 

验证了上面的规律,所以正真的解题程序如下:

#include <iostream>
#include <stdio.h>
#include <string.h>
#include <string>
#include <math.h>

using namespace std;

int n;
int a[10005];
int main()
{
    scanf("%d",&n);
    int ans=0;
    for(int i=1;i<16;i++)
    {
        int x =(int)pow(2.0,i);
        if(x>n)
        {ans=i; break;}
    }
    printf("%d",(int)pow(2.0,ans-1));
}

 

这类规律题,一般在纸上就能把规律找出来。

奖励园豆:5
Shendu.CC | 老鸟四级 |园豆:2138 | 2018-03-24 08:17

谢谢您!虽然我昨天晚上就想出来了,但是还是表示感谢!附上我的代码:

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int maxN=10001;
int n;
bool flag[maxN];
int main() {
    memset(flag, true, sizeof(flag)); 
    scanf("%d", &n);
    int sum=0, t=1, k=2;
    for(int i=1; i<=n; i++) 
        if(i&1) {
            flag[i]=false;
            sum++;        
        }
    while(sum<n-1) {
        for(int i=t*2; i<=n; i+=k*2)
            //if((i+k*2)>n) break;
            //else {
            if(i<=n) {
                flag[i]=false;
                sum++;
                if(sum==n-1) break;
            }
            else break;
            //}
        t*=2, k*=2;
    }
    for(int i=1; i<=n; i++)
        if(flag[i]) printf("%d", i);
    return 0;
}

 

Aehnuwx | 园豆:263 (菜鸟二级) | 2018-03-24 14:20

@Antinue: 我的代码提交是AC的吗

Shendu.CC | 园豆:2138 (老鸟四级) | 2018-03-24 14:23
其他回答(1)
0

想到了约瑟夫环。可以参考一下约瑟夫环算法。

随风行云 | 园豆:936 (小虾三级) | 2018-03-24 00:22
清除回答草稿
   您需要登录以后才能回答,未注册用户请先注册