高校挑战赛:观看世界杯--限制排序算法

试题来源:http://student.csdn.net/mcs/programming_challenges?&page=1  观看世界杯

  

  以前在学校参加每年的ACM程序设计大赛,感觉程序算法还是挺有意思的,这两天发现一个网站上放出一些算法试题,有点当年的那种心情,看到了,感觉能干掉,那就干掉它。目前还在公司守夜中,闲着没事就试了试算法题。

  速手打,没有详细检查,可能有瑕疵请见谅,但是读题、解题、算法设计,一个不少。

 if(type == 1){...} 这段里,虽然写的有点小复杂,但是是个简单的优化,呵呵。

  做事前,先看清,再下手。程序猿时间有限,不要随意浪费,错误的解读,终会造成一个不正确的结果。

class Program
    {
        /*
         *     世界杯正在火热进行中,室友不惜睡眠时间,凌晨起来观看,但Njzy对此不是很感兴趣,他在思考一个问题:
         * 假设世界杯观看台上有n个座位,排成一排,游客们来到这里自由占位。一般情况下,一个游客首先考虑的座位
         * 肯定是两边都没人的座位,其次考虑的是一边没人的座位,最后没得考虑,只能随便选一张两边都是人的座位。
         * 假设有n个游客依次到场占位,每个人都是按照上述规则选择自己的位子,Njzy就在思考这n个游客占位的可能顺
         * 序有多少种,你能帮助他? 输入描述: 有多组测试数据,每组测试数据包括一个正整数n(0<n<1000000)。 输出
         * 描述: 对于每组数据,由于答案可能会很大,所以输出:答案%1000000007
         *
         * **************************************
         *
         * 首先仔细读题:
         *  1.世界杯观看台上有n个座位,这n个座位有n个依次到场的游客来坐。
         *    解析:这里面隐藏两点(这两点很重要,如果没有读出这两点,计算会非常复杂):
         *                  a.座位数等于游客数
         *                  b.游客有入场顺序(此题中游客的入场顺序为1,2,3,4...)
         * (限制型排序算法)
         *
         *
         *  2.首先考虑的座位肯定是两边都没人
         *
         *  3.其次考虑的是一边没人的座位
         *
         *  4.只能随便选一张两边都是人的座位
         *
         *
         * 输出结果:
         * 表示游客的选座方法(顺序号对应游客的入场顺序)。
         *
         *
         * 修改personIndex 的值表示入场的人数(座数),为题中n(0<n<1000000)
         * 如果只求出总选座的方法,可以注释 Console.WriteLine(string.Join(",", _SiteArray));
         * 没有输出,提高程序的计算效率。
         */

        static void Main(string[] args)
        {
            //假设:人数、座位数(1,2,3...表示游客的入场顺序)
            int _PersonCount = 4;

            int[] _SiteArray = new int[_PersonCount];

            int personIndex = 1;
            int type = 2;

            switch (_SiteArray.Length)
            {
                case 0: type = -1; break;
                case 1: type = 0; break;
                case 2: type = 1; break;
                case 3: type = 2; break;
                default: type = 2; break;
            }

            FuncRun(ref _SiteArray, ref personIndex,  type);

            Console.WriteLine("总共 {0} 种选座的方法",ResCount);
        }

        static void Swap(ref int l, ref int r)
        {
            l = l ^ r;
            r = l ^ r;
            l = l ^ r;
        }

        static int ResCount = 0;

        static void FuncRun(ref int[] _SiteArray, ref int personIndex,  int type)
        {
            if (personIndex > _SiteArray.Length)
            {
                Console.WriteLine(string.Join(",", _SiteArray));
                ResCount++;
                return;
            }

            if (type == 2)
            {
                //---------------------------------------------------
                //首先考虑的座位肯定是两边都没人
                for (int i = 1; i < _SiteArray.Length - 1; i++)
                {
                    if (_SiteArray[i] > 0)
                        continue;

                    if (_SiteArray[i - 1] == 0 && _SiteArray[i + 1] == 0)
                    {
                        _SiteArray[i] = personIndex++;
                        FuncRun(ref _SiteArray, ref personIndex,  type);
                        //数据恢复
                        personIndex--;
                        _SiteArray[i] = 0;
                    }
                }
                type--;
            }

            //---------------------------------------------------
            //其次考虑的是一边没人的座位
            if (type == 1)
            {
                if (personIndex <= 1 || _SiteArray.Length < 3)
                    return;

                if (_SiteArray[0] == 0 && _SiteArray[1] == 0)
                {
                    _SiteArray[0] = personIndex++;
                    FuncRun(ref _SiteArray, ref personIndex,  type);
                    //数据恢复
                    personIndex--;
                    _SiteArray[0] = 0;
                }

                for (int i = 1; i < _SiteArray.Length - 1; i++)
                {
                    if (_SiteArray[i] > 0)
                        continue;

                    if (_SiteArray[i - 1] == 0)
                    {
                        _SiteArray[i] = personIndex++;
                        FuncRun(ref _SiteArray, ref personIndex,  type);
                        //数据恢复
                        personIndex--;
                        _SiteArray[i] = 0;
                    }
                    else if (_SiteArray[i + 1] == 0)
                    {
                        _SiteArray[i] = personIndex++;
                        FuncRun(ref _SiteArray, ref personIndex,  type);
                        //数据恢复
                        personIndex--;
                        _SiteArray[i] = 0;
                    }
                }

                if (_SiteArray[_SiteArray.Length - 1] == 0 && _SiteArray[_SiteArray.Length - 2] == 0)
                {
                    _SiteArray[_SiteArray.Length - 1] = personIndex++;
                    FuncRun(ref _SiteArray, ref personIndex,  type);
                    //数据恢复
                    personIndex--;
                    _SiteArray[_SiteArray.Length - 1] = 0;
                }
                type--;
            }

            //---------------------------------------------------
            //只能随便选一张两边都是人的座位
            if (type == 0)
            {
                for (int i = 0; i < _SiteArray.Length; i++)
                {
                    if (_SiteArray[i] == 0)
                    {
                        _SiteArray[i] = personIndex++;
                        FuncRun(ref _SiteArray, ref personIndex,  type);
                        //数据恢复
                        personIndex--;
                        _SiteArray[i] = 0;
                    }
                }
            }
        }
    }
时间: 2024-10-12 21:28:29

高校挑战赛:观看世界杯--限制排序算法的相关文章

常见排序算法导读(10)[基数排序]

与前面介绍的7种排序算法不同,基数排序(Radix Sort)是基于多关键字排序的一种排序算法.也就是说,前面介绍的7种排序算法是建立在对单个元素关键字比较的基础之上,而基数排序则是采用"分配"与"收集"的办法,用对多关键字进行排序的思想实现对单个关键字的排序. 基数排序的典型例子当然就是扑克牌排序啦,几乎所有的数据结构教科书都会讲到,原因是形象易懂.每张扑克牌都有两个关键字:花色和面值.假定有序关系为: 花色: 黑桃 < 红桃 < 梅花 < 方块

排序算法及其比较--数据结构课设

 排序算法及其比较 课程设计报告 一. 设计内容 编程实现希尔.快速.堆排序.归并排序算法,并利用程序统计每种算法的执行时间.要求随机产生10000(或50000. 100000. 200000,由用户选择)个数据存入数据文件,然后读数据文件,分别采用不同排序方法进行排序,将结果存入另一个文件中. 二. 设计思想描述 1.  总思想 本程序采用模块化设计思想,分为产生随机数模块,计时模块,写入磁盘模块,读出磁盘模块,希尔排序模块,快速排序模块,堆排序模块,归并排序模块,计时模块.对常见的4 种经

详解四大排序算法

作者: Dsir 分类: PHP 发布时间: 2017年08月04日 07时40分 详解四大排序算法 如何排序? NBA总决赛正在如火如荼的进行,老詹也正朝着他的第5个总亚军前进着.假设骑士队队员在运动场上排列成一队,如图所示,所有队员已经站好,准备热身,现在需要按身高从低到高 为队员们排队(最矮的站在左边),给他们照一张集体照,应该怎么排队呢? 在排序这件事情上,人与计算机程序相比有以下优势:我可以同时看到所有的队员,并且可以立刻找出最高的一个,毫不费力得测量和比较每一个人的身高.而且队员们不

经典排序算法 - 冒泡排序Bubble sort

 原文出自于 http://www.cnblogs.com/kkun/archive/2011/11/23/bubble_sort.html 经典排序算法 - 冒泡排序Bubble sort 原理是临近的数字两两进行比较,按照从小到大或者从大到小的顺序进行交换, 这样一趟过去后,最大或最小的数字被交换到了最后一位, 然后再从头开始进行两两比较交换,直到倒数第二位时结束,其余类似看例子 例子为从小到大排序, 原始待排序数组| 6 | 2 | 4 | 1 | 5 | 9 | 第一趟排序(外循环) 第

排序算法比较及其应用

一.将各种数据排序 只要实现了Comparable接口的数据类型就可以被排序. 但要使算法能够灵活地用不同字段进行排序,则是后续需要考虑的问题. 1.指针排序 在Java中,指针操作是隐式的,排序算法操作的总是数据引用,而不是数据本身. 2.键不可变 如果在排序后,用例还可以改变键值,那么数组很可能就不是有序的了.类似,优先队列也会乱套. Java中,可以用不可变数据类型作为键来避免这个问题,如String,Integer,Double和File都是不可变的. 3.廉价交换 使用引用的另一个好处

选择排序 —— 排序算法系列

假设我们有如下一个数组: 使用选择排序算法对这个数组进行排序,步骤如下: 第 1 次 在下标0到6之间找到最小的数字,我们可以发现最小的数字是15,它在下标为4的位置上: 把下标4上面的数字跟下标0上面的数字互换,得到排序如下图的数组: 第 2 次 在下标1到6之间找到最小的数字,我们可以发现最小的数字是33,它在下标为5的位置上: 把下标5上面的数字跟下标1上面的数字互换,得到排序如下图的数组: 第 3 次 在下标2到6之间找到最小的数字,我们可以发现最小的数字是48,它在下标为5的位置上:

排序算法Java版,以及各自的复杂度,以及由堆排序产生的top K问题

常用的排序算法包括: 冒泡排序:每次在无序队列里将相邻两个数依次进行比较,将小数调换到前面, 逐次比较,直至将最大的数移到最后.最将剩下的N-1个数继续比较,将次大数移至倒数第二.依此规律,直至比较结束.时间复杂度:O(n^2) 选择排序:每次在无序队列中"选择"出最大值,放到有序队列的最后,并从无序队列中去除该值(具体实现略有区别).时间复杂度:O(n^2) 直接插入排序:始终定义第一个元素为有序的,将元素逐个插入到有序排列之中,其特点是要不断的 移动数据,空出一个适当的位置,把待插

排序算法总结

各种排序算法总结  排序算法  插入排序 冒泡排序  选择排序  归并排序  快速排序 堆排序  计数排序  基数排序  桶排序  思想  构建有序序列 两两交换 每次找一个最小值 分治法思想 分治法思想 最小堆.最大堆 数字本身的属性  对数据选择多种基数  函数的映射关系.Hash  数据结构  数组  数组  数组  数组 不定   数组 数组 数组  数组  最差时间复杂度 O(n^2)   O(n^2)   O(n^2)   O(n*lgn)  O(n^2).改进O(n*lgn)  O

七大常见排序算法总结

文档版本 开发工具 测试平台 工程名字 日期 作者 备注 V1.0 2016.04.06 lutianfei none V1.1 2016.07.16 lutianfei 增加了归并排序说明 V2.0 2016.07.19 lutianfei 完善了排序算法的总结 排序另一种分法 外排序:需要在内外存之间多次交换数据才能进行 内排序: 插入类排序 直接插入排序 希尔排序 选择类排序 简单选择排序 堆排序 交换类排序 冒泡排序 快速排序 归并类排序 归并排序 排序方法 平均情况 最好情况 最坏情况