首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > .NET > C# >

【C# 每日一题3】求第K大的数解决办法

2012-02-25 
【C# 每日一题3】求第K大的数C# code原题如下:DescriptionThere are two sequences A and B with N (1N1

【C# 每日一题3】求第K大的数

C# code
原题如下:DescriptionThere are two sequences A and B with N (1<=N<=10000) elements each. All of the elements are positive integers. Given C=A*B, where '*' representing Cartesian product, c = a*b, where c belonging to C, a belonging to A and b belonging to B. Your job is to find the K'th largest element in C, where K begins with 1.InputInput file contains multiple test cases. The first line is the number of test cases. There are three lines in each test case. The first line of each case contains two integers N and K, then the second line represents elements in A and the following line represents elements in B. All integers are positive and no more than 10000. K may be more than 10000.OutputFor each case output the K'th largest number.Sample Input22 13 45 62 32 14 8Sample Output248

解释一下,定义数组A和数组B,里面都有n(1<=n<=10000)个元素,之后定义C数组,里面的元素c=a*b,a属于A,b属于B,之后求出C数组中第K大的数据!
输入:t代表有t组测试用例
输入N和K代表A和B数组中有N个元素,并且求C数组中的第K大的数据
之后输入A数组中的N个数据,和B数组中的N个数据!

例子(其中的一个测试用例):
1 ->一组测试用例
2 3 ->数组A B中分别有两个元素,求C中第3大的元素
2 1 ->数组A中的元素
4 8 ->数组B中的元素

之后C中的元素为 8 16 4 8,第三大的数据为 8

题记:
这个题暴力搜索是可以的,大家看看有没有更好的办法,暴力搜索的可以练一下自己的代码,贴一下!


[解决办法]
算法题,帮顶学习了
[解决办法]
以前做过,二分就可以了。n*log(n)的,如果用内插法的话,效率会更好一些。
[解决办法]
这是以前写的一个,大概可以算100万的数据规模,用的是二分,如果有时间可以改个内插法的试试

C# code
using System;namespace CSharpTest{    class Program    {        public static int[] A = new int[1000000], B = new int[1000000];        public static Random Rnd = new Random(2010);//统一一个随机种子好验证        public static void FillRandomValues(int[] arr)//随机填充        {            for (var i = 0; i < arr.Length; i++)                arr[i] = Rnd.Next();        }        public static void Main()        {            FillRandomValues(A);            FillRandomValues(B);            //排序            Array.Sort<int>(A);            Array.Sort<int>(B);            //根据输入的K输出结果            while (true)            {                long k;                if (long.TryParse(Console.ReadLine(), out k))                {                    if (k == 0) break;                    Console.WriteLine(KthElement(k));                }            }        }        //求第K个元素        static long KthElement(long k)        {            //该数肯定位于upper和lower之间            long upper = (long)A[A.Length - 1] * B[B.Length - 1], lower = A[0] * B[0];            return Solve(upper, lower, k);        }        //二分查找该值        static long Solve(long upper, long lower, long count)        {            if (upper == lower) return upper;            long mid = (upper + lower) >> 1;            if (Counter(mid) >= count)                return Solve(upper, mid + 1, count);            if (Counter(mid - 1) < count)                return Solve(mid - 1, lower, count);            return mid;        }        //统计比指定value大的数有多少个        static long Counter(long value)        {            int i = 0, j = B.Length - 1;            long count = 0;            while (i < A.Length && j >= 0)            {                if ((long)A[i] * (long)B[j] > value)                {                    count += A.Length - i;                    j--;                }                else                    i++;            }            return count;        }    }}
[解决办法]
用堆排序求第K大数据比较好
------解决方案--------------------


来学习。
[解决办法]
来学习
[解决办法]

探讨
之后C中的元素为 8 16 4 8,第三大的数据为 8

[解决办法]
用分治的方法把集合分成大于某个值、等于某个值、小于某个值的3个子集,如果“小于某个值”的个数小于K,则第K大的数在另外两个子集中;相对的,还有另外两种情况,第K大的数分别在“等于某个值”、“小于某个值”的集合中。当集合的个数大于某个临界值时候,采用这种方法可以有近似线性的复杂度。
[解决办法]
编程之美上那个 寻找最大的k个数 
快速排序或堆排序后 二分搜索

[解决办法]
坐在旁边围观了啊
[解决办法]
来学习
[解决办法]
探讨

引用:

用分治的方法把集合分成大于某个值、等于某个值、小于某个值的3个子集,如果“小于某个值”的个数小于K,
求解释!!近似线性!!

[解决办法]
当然。。。这个只是排序而已。。。算法课上都会学的= = 。。。与这道题目还是不一样的
[解决办法]
编程珠玑第一篇,位图算法。
[解决办法]
有个想法,对AB两组每个数求对数,然后根据对数值取整分组,组编号就是取整后的对数,两组数的对数每组间元素数相乘对应到组号相加的数值,这样就能得到一个C中元素由大至小数量的列表,就可以确定K的范围

[解决办法]
OJ啊= =
[解决办法]
学习下
[解决办法]
ding
[解决办法]
算法书上不是有这个吗?最快可以达到O(n)
[解决办法]
来学习一下~~
[解决办法]
持续关注
[解决办法]
学习啦!
[解决办法]
很多人没看题目就发言。。。。。
[解决办法]
C# code
Sample Input
[解决办法]
探讨
这是以前写的一个,大概可以算100万的数据规模,用的是二分,如果有时间可以改个内插法的试试

C# code

using System;

namespace CSharpTest
{
class Program
{
public static int[] A = new int[1000000], B = new int[1000000];
……

[解决办法]
来学习了
[解决办法]
俺是打酱油的。
[解决办法]
mark一下,明天有空就做。
BTW,如果没有可用分,可以M我
[解决办法]
学习一下
[解决办法]

[解决办法]
ding一下!~
[解决办法]
学习!!
------解决方案--------------------


学习了
[解决办法]
学习了学习了,读了半天的题,嗬嗬嗬
[解决办法]
学习了。。。每周一题1&2也都看了,不错。
[解决办法]
1&2还看的懂一些,3的,算法。。。算了,没办法。。。。学习吧。
[解决办法]
11111111111111111111111111
[解决办法]
用位图或者快排
但是快排的时候不要全排,主要只需要排前K个就行,从K+1遍历剩下的,如果比第K个大,就替换。
复杂度KlogK
[解决办法]
何必每个都算呢,先对A,B倒序排序,再遍历,最多执行i+j次就了(i就A的数量,j是B的)

C# code
namespace FindN{    public class Comparer : IComparer<int>    {        public int Compare(int x, int y)        {            return x.CompareTo(y) * -1;        }    }    class Program    {        static void Main(string[] args)        {            List<int> a = new List<int>();            List<int> b = new List<int>();            a.Add(2);            a.Add(3);            a.Add(7);            //a.Add(9);            b.Add(4);            b.Add(8);            b.Add(5);            Comparer c = new Comparer();            a.Sort(c);            b.Sort(c);            int v =Program.Find(a, b, 3);        }        static int Find(List<int> a, List<int> b, int n)        {            int ac = a.Count;            int bc = b.Count;            int av = a[0];            int bv = b[0];            int c = 0;            for (int i = 1; i < a.Count;)            {                for (int j = 1; j < b.Count; )                {                    if (b[j] > a[i])                    {                        if (c + ac > n)                        {                            return a[n - c] * b[j];                        }                        c += ac;                        bv = b[j];                        j++;                    }                    else                    {                        if (c + bc > n)                        {                            return a[i] * b[n - c];                        }                        c += bc;                        av = a[i];                        i++;                    }                }            }            throw new Exception();        }    }}
[解决办法]
前K大的问题,一定是O(n)的,30年前早有定论。
看算法导论和TAOCP
[解决办法]
学习了
[解决办法]
嘿嘿,笨狼兄还是仔细看看此题吧,哪有这么简单?

探讨
前K大的问题,一定是O(n)的,30年前早有定论。
看算法导论和TAOCP

[解决办法]
都是强人,算法太复杂了
[解决办法]
算法不及格,学习
[解决办法]
正在思考
[解决办法]
典型的TOP K问题,可以考虑用容量为K的大顶堆来解决
[解决办法]
这个帖子的标题误导了N多人。。。。。建议楼主改一下标题
[解决办法]
探讨

这个帖子的标题误导了N多人。。。。。建议楼主改一下标题

[解决办法]
刚发现这里真是聚宝盆,好好学习


[解决办法]
学习了,看到算法题就头痛,。
[解决办法]
不知道啊.以后再看看书,再来回答各位了.
[解决办法]
希望以后会懂得更多啊

[解决办法]
ertgwygwyweywert

热点排行