• HDU1443_Joseph_约瑟环


    题目大意: 有k个好人跟k个坏人按顺序坐着,然后按第m个杀人,求出把坏人全部先杀光的m的最小值。   0<k<14。典型的约瑟环问题。 解题思路: 一开始看见数据量那么小,还以为暴力一定可以出来,结果,好吧,当k为0以上时,时间大得惊人,自己暴力的方法还是有很大问题啊。 比较标准的做法是:在这么多个人中,始终用start跟end来确定好人那个序列的位置。 比如一开始是1 2 3 4 5 6,那么start = 0,end = 3(从0开始计数)当m等于5的时候,kill后就剩下1 2 3 4 6 ,重新拍下序列变成 6 1 2 3 4 ,这时候 start = ((start-m)%n+n)%n; end =  ((end-m)%n+n)%n; n是当前剩下的人数。定完位置之后,kill的位置为kill = (m-1)%n; 这样就可以做了。 AC代码:
    #include
    using namespace std;
    
    bool joseph(int k, int m)
    {
        int start = 0, end = k - 1; //定位,定好人的位置
        int kill;//杀人的序号
        for(int n = 2 * k; n > k; n--) //n代表人数
        {
            kill = (m - 1) % n;
            if(kill >= start && kill <= end)
            {
                return false;
            }
            start = ((start - m) % n + n) % n;//定位,加n模n是为了防止负数
            end = ((end - m) % n + n) % n;
        }
        return true;
    }
    
    int main(void)
    {
        int f[14];
        for(int i = 1; i < 14; i++)
            for(int j = 1; ; j++)
            {
                if(joseph(i, j))
                {
                    f[i] = j;
                    break;
                }
            }
        int k;
        while(scanf("%d", &k), k)
        {
            printf("%d\n", f[k]);
        }
        return 0;
    }
    
    TLE代码:
    #include
    using namespace std;
    const int MAX = 30;
    const int M = 100005;
    int main(void)
    {
    
        int pe[MAX];
        for(int k = 11; k < 14; k++)
        {
            bool mark[MAX];
    
            for(int i = 0; i <= k; i++)
                pe[i] = 1;
            for(int i = k + 1; i <= 2 * k; i++)
                pe[i] = 2;//bad guys
            int min = 0;//结果
            bool flag = false;
            for(int m = 1; ; m++)
            {
                int count = 0, index = 1;
                int bad = k;//坏人
                //int m = 30;
                memset(mark, false, sizeof(mark));
    
                while(1)
                {
                    if(mark[index] == true)
                    {
                        if(index == 2 * k) //指向的移动
                        {
                            index = 1;
                        }
                        else
                            index++;
                        continue;
                    }
    
                    count++;
                    if(count == m)
                    {
                        if(pe[index] == 1)//杀了好人
                            break;
                        else
                        {
                            mark[index] = true;
                            bad--;
                            if(bad == 0)
                            {
                                min = m;
                                flag = true;
                                break;
                            }
                        }
                        count = 0;//重新计数
                    }
    
                    if(index == 2 * k) //指向的移动
                    {
                        index = 1;
                    }
                    else
                        index++;
                }
    
                if(flag)
                    break;
            }
            //for(int i = 1; i <= 2*k; i++)
            //	printf("%d ", mark[i]);
            //printf("\n");
            printf("%d\n", min);
        }
        return 0;
    }
    
  • 相关阅读:
    py3学习笔记0(入坑)
    为什么很多PHP文件最后都没有?>
    作业
    凯撒密码、GDP格式化输出、99乘法表
    作业4
    作业3
    turtle库基础练习
    作业2
    作业1
    编译原理有限自动机的构造与识别
  • 原文地址:https://www.cnblogs.com/cchun/p/2520224.html
Copyright © 2020-2023  润新知