LinuxSir.cn,穿越时空的Linuxsir!

 找回密码
 注册
搜索
热搜: shell linux mysql
楼主: yongjian

[算法]数列排序

[复制链接]
发表于 2006-8-2 16:53:38 | 显示全部楼层

  1.    B   90  29  14   7   5   2
  2. A
  3. 100   190 129 114 107 105 102
  4.   99   189 128 113 106 104 101
  5.   98   188 127 112 105 103 100
  6.   86   176 115 100  93  91  88
  7.   20   110  49  34  27  25  22
  8.    1    91  30  15   8   6   3
复制代码



看一下这个数组,很难找到规律的。
回复 支持 反对

使用道具 举报

发表于 2006-8-2 17:14:01 | 显示全部楼层
A + B[j] >= A + B[v] u >=i v >=j
这也是我的算法工作的原理。
回复 支持 反对

使用道具 举报

发表于 2006-8-2 17:36:23 | 显示全部楼层
Post by Iambitious
A + B[j] >= A + B[v] u >=i v >=j



P(3,1)=A[3]+B[1]>(5,1)=A[5]+B[1];
P(1,3)=A[1]+B[3]>(1,5)=A[1]+B[5];
这是肯定能确定的

P(3,1)和P(1,3),P(5,1)和P(1,5)怎么确定大小,横向和纵向这种对比是容易的。


我有一个笨的算法(如果数组中元素是非0的正短整数)
P[]中两个元素最小的相差值为1。
P[n+1]  n最大应该为A[0]+B[0];(由于数组是从0开始编号)
但这个我编译始终有错,数组后面的一些元素总出错,不知道是什么原因,会不会是溢出了;


  1. #include <stdio.h>
  2. int main()
  3. {
  4.     int p[191];
  5.     int a[]={100,99,98,86,20,1};
  6.     int b[]={90,29,14,7,5,2};
  7.     int i,m,n,s;
  8.     for (n=0;n<6;n++)
  9.     {
  10.         for (m=0;m<6;m++)
  11.         {
  12.             s=a[n]+b[m];
  13.             p[s]=s;
  14.             printf("s%d,%d\n",s,p[s]);
  15.         }
  16.     }

  17.     for (i=0;i<191;i++)
  18.     {
  19.         printf("p%d,%d\n",i,p[i]);
  20.     }
  21.     return 0;
  22. }
复制代码
回复 支持 反对

使用道具 举报

发表于 2006-8-2 19:27:58 | 显示全部楼层
你可以看看败者树的相关知识,有助于你解决这道题。
参看严慰敏所写的数据结构的外排序一章。
回复 支持 反对

使用道具 举报

发表于 2006-8-2 19:38:40 | 显示全部楼层
你的程序通过编译没有问题,估计你想问的是为什么p数组里面有很多奇怪的值吧,那主要是因为
p数组没有被初始化。
回复 支持 反对

使用道具 举报

发表于 2006-8-2 21:02:05 | 显示全部楼层
多谢指出问题所在,重新调整后的代码


  1. #include <stdio.h>
  2. int main()
  3. {
  4.     int p[191];
  5.     int w[36];
  6.     int a[]={100,99,98,86,20,1};
  7.     int b[]={90,29,14,7,5,2};
  8.     int i,m,n,s,t,x=0;
  9.     //初始p[]
  10.     for (i=0;i<191;i++)
  11.     {
  12.         p[i]=-1;
  13.     }
  14.     //求出a[]+b[]
  15.     for (n=0;n<6;n++)
  16.     {
  17.         for (m=0;m<6;m++)
  18.         {
  19.             s=a[n]+b[m];
  20.             p[s]=s;
  21.             //printf("p%d,%d\n",s,p[s]);
  22.         }
  23.     }
  24.     // 整理p[]
  25.     for (i=0;i<191;i++)
  26.     {
  27.         if( p[i]!=-1)
  28.         {
  29.             //printf("p%d,%d\n",i,p[i]);
  30.             t=p[i];
  31.             w[x]=t;
  32.             printf("w%d,%d\n",x,w[x]);
  33.             x++;
  34.         }
  35.     }
  36.     return 0;
  37. }
复制代码
回复 支持 反对

使用道具 举报

发表于 2006-8-3 11:32:32 | 显示全部楼层
昨天做topcoder遇到了一道题,跟这道题有点类似,但是有特殊的地方,解法很有意思,大家考虑考虑。

题目如下:
考虑一个n * n 的矩阵A[1..n][1..n],A[j] = i * j(1<=i,j<=n),求第k个最小的A[j]。

数据范围:
1<=n<=100000
1<=k<=min(1000000000, n * n)

要求:

程序在2秒内返回正确结果

例子:
n=3,k=7
A[1..3][1..3]:
1 2 3
2 4 6
3 6 9
result=6
回复 支持 反对

使用道具 举报

发表于 2006-8-8 03:58:29 | 显示全部楼层
楼上那题,二分答案吧
回复 支持 反对

使用道具 举报

发表于 2006-8-8 04:15:10 | 显示全部楼层

  1. yuhch@localhost ~/tmp $ cat tmp.c
  2. #include <stdio.h>
  3. #include <stdlib.h>
  4. long long N, K;
  5. long long GetAns1(long long x) {
  6.    long long t = 0, i, j;
  7.    for (i = 0; i < N; i ++)
  8.       t += ((j = (x - 1) / (i + 1)) > N ? N : j);
  9.    return t;
  10. }
  11. long long GetAns2(long long x) {
  12.    long long t = 0, i, j;
  13.    for (i = 0; i < N; i ++)
  14.       t += ((j = x / (i + 1)) > N ? N : j);
  15.    return t;
  16. }
  17. int main() {
  18.    long long f, r, m, t1;
  19.    freopen("pro.in", "r", stdin);
  20.    scanf("%lld%lld", &N, &K);
  21.    f = 0;
  22.    r = (long long)N * (long long)N;
  23.    while (1) {
  24.       m = (f + r) / 2;
  25.       if ((t1 = GetAns1(m) + 1) <= K && (GetAns2(m)) >= K)
  26.          break;
  27.       if (t1 > K)
  28.          r = m;
  29.       else
  30.          f = m + 1;
  31.    }
  32.    printf("%lld\n", m);
  33.    return 0;
  34. }

  35. yuhch@localhost ~/tmp $ cat pro.in
  36. 100000 1000000000
  37. yuhch@localhost ~/tmp $ time make run
  38. ./tmp
  39. 204535821

  40. real    0m0.207s
  41. user    0m0.202s
  42. sys     0m0.002s
复制代码
回复 支持 反对

使用道具 举报

发表于 2006-8-8 08:38:29 | 显示全部楼层
very good!
in truth,
  1. import java.util.*;
  2. public class ProductsMatrix {
  3.     public long nthElement(int n, int k) {
  4.          long min = 1;
  5.          long max = (long)n * (long)n;
  6.          while(min < max){
  7.                  long mid = (max + min) / 2;
  8.                  long count = 0;
  9.                  for(int i = 1; i <= n; i++){
  10.                          count += Math.min(n, mid / i);
  11.                  }
  12.                  if(count < k){
  13.                          min = mid + 1;
  14.                  }
  15.                  else{
  16.                          max = mid;
  17.                  }
  18.          }
  19.         return min;
  20.     }
  21. }
复制代码
is ok
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

快速回复 返回顶部 返回列表