输入 : N  M

要找到长度为 N 的等差数列,要求数列中每个数字都可以表达成 a^2 + b^2 的和, 数字大小不超过M^2 + M^2

输出: 等差数列首元素 间隔 (多组答案分行输出)

解题思路:因为等差数列的数字都是平房和数  所以先生成所有的 从0 - M^2 + M^2的平方和数 去掉相同的并从小到大排序

然后对 所有间隔 、 首元素 做循环 判断能否找到以该首元素和间隔为条件的其他N-1个需要的数字 可以就存成答案;

提交后超时了.... test 5的时候 超了5s 正在想简化办法 超时的代码

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <math.h>
  4.  
  5. #define MAXN 200000
  6. int cmp(const void *va, const void *vb)
  7. {
  8. return (*(int *)va) - (*(int *)vb);
  9. }
  10.  
  11. int find(int * bisquare, int binum, int num)
  12. {
  13. int i;
  14. for(i = 0; i < binum; i++)
  15. {
  16. if(bisquare[i] == num)
  17. return 1;
  18. }
  19. return 0;
  20. }
  21.  
  22. int main()
  23. {
  24. FILE *in, *out;
  25. in = fopen("ariprog.in", "r");
  26. out = fopen("ariprog.out", "w");
  27.  
  28. int bisquare[40000]; //存储所有可以用的平方数
  29. int binum = 0; //存储可用平方数的个数
  30. int ans[10000][2];
  31. int anum = 0; //答案个数
  32. int gap[25]; //存储间隔
  33. int M, N;
  34. int i, j, k;
  35.  
  36. for(i = 0; i < 40000; i++)
  37. {
  38. bisquare[i] = MAXN;
  39. }
  40.  
  41. fscanf(in, "%d %d", &N, &M);
  42.  
  43. for(i = 0; i <= M; i++)
  44. {
  45. for(j = 0; j <= M; j++)
  46. {
  47. bisquare[binum] = i * i + j * j;
  48. binum++;
  49. }
  50. }
  51.  
  52. qsort(bisquare, binum, sizeof(bisquare[0]), cmp);
  53.  
  54. //去掉相同的平方和数
  55. int numt = binum;
  56. for(i = 0; i < numt; i++)
  57. {
  58. if(bisquare[i] == bisquare[i + 1])
  59. {
  60. bisquare[i] = MAXN;
  61. binum--;
  62. }
  63. }
  64. qsort(bisquare, numt, sizeof(bisquare[0]), cmp);
  65.  
  66. int flag;
  67. //对所有间隔大小, 所有起始位搜索
  68. for(i = 1; i <= M * M * 2; i++)
  69. {
  70. for(j = 0; j < binum - N + 1; j++)
  71. {
  72. flag = 1;
  73. for(k = 1; k < N; k++)
  74. {
  75. if(find(bisquare, binum, bisquare[j] + k * i) == 0)
  76. {
  77. flag = 0;
  78. break;
  79. }
  80. }
  81. if(flag == 1)
  82. {
  83. ans[anum][0] = bisquare[j];
  84. ans[anum][1] = i;
  85. anum++;
  86. }
  87. }
  88. }
  89.  
  90. if(anum > 0)
  91. {
  92. for(i = 0; i < anum; i++)
  93. {
  94. fprintf(out, "%d %d\n", ans[i][0], ans[i][1]);
  95. }
  96. }
  97. else
  98. {
  99. fprintf(out, "NONE\n");
  100. }
  101.  
  102. return 0;
  103.  
  104. }

----------------

对于查找的办法做了化简 之前用find函数一个一个的比较 但实际上 我们只需要搜索与当前首元素右侧相邻的一些数字, 若发现搜索的数字与当前首元素的差值已经大于n个间隔了 则返回查找失败

方法:存储相邻两个数之间的差值, 从当前首元素开始对差值求和,求和值不能大于间隔

修改的部分代码:

  1. for(i = ; i < binum - ; i++)
  2. {
  3. gap[i] = bisquare[i + ] - bisquare[i];
  4. }
  5. //..................
  6. //if(find(bisquare, binum, bisquare[j] + k * i) == 0)
  7. //{
  8. // flag = 0;
  9. // break;
  10. //}
  11. int inter = ;
  12. while(inter < i && m <= binum - )
  13. {
  14. inter = inter + gap[m];
  15. m++;
  16. }
  17. if(inter != i)
  18. {
  19. flag = ;
  20. break;
  21. }
  22. //....................

修改后 test5 通过了 但test6 还是超时了.... 还要继续化简

----------------------

继续对查找过程优化 用目前最快的二分查找 O(logn) 的 查找范围是首元素之后的元素 真的是数量级的变快了 test5从 4s+ 变到了 0.389s 只是test 6 仍然超时了... 在自己电脑上跑了一下 差不多10s的样子会出来结果 也比之前的查找快多了  果然,学了就要用啊........    查找的算法见下面  还需要继续优化

  1. int BinarySearch(int * T, int left, int right, int x)
  2. {
  3.  
  4. int l = left, r = right;
  5. while(l < r)
  6. {
  7. int m = (l + r) / ;
  8. int aa= T[m];
  9. if(T[m] == x)
  10. {
  11. return ;
  12. }
  13. else if(T[m] < x)
  14. {
  15. l = m + ;
  16. }
  17. else
  18. {
  19. r = m - ;
  20. }
  21. }
  22. if(T[l] == x)
  23. {
  24. return ;
  25. }
  26. return ;
  27. }

---------------------------------------------------------

用了个及其NC的优化办法  把间隔循环的上限设到 3000  , 首元素循环上限设到 第10000个元素  算是半个作弊了.... 代码主要就是在这两个地方耗时间。间隔循环是 M^2数量级个,首元素binum是(M+1)^2的量级。这两个一嵌套就是M^4  不知道用什么规则化简, 只好强制设上限了。 AC代码

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <math.h>
  4.  
  5. #define MAXN 200000
  6. int cmp(const void *va, const void *vb)
  7. {
  8. return (*(int *)va) - (*(int *)vb);
  9. }
  10.  
  11. int BinarySearch(int * T, int left, int right, int x)
  12. {
  13.  
  14. int l = left, r = right;
  15. while(l < r)
  16. {
  17. int m = (l + r) / ;
  18. int aa= T[m];
  19. if(T[m] == x)
  20. {
  21. return ;
  22. }
  23. else if(T[m] < x)
  24. {
  25. l = m + ;
  26. }
  27. else
  28. {
  29. r = m - ;
  30. }
  31. }
  32. if(T[l] == x)
  33. {
  34. return ;
  35. }
  36. return ;
  37. }
  38.  
  39. int main()
  40. {
  41. FILE *in, *out;
  42. in = fopen("ariprog.in", "r");
  43. out = fopen("ariprog.out", "w");
  44.  
  45. int bisquare[]; //存储所有可以用的平方数
  46. int binum = ; //存储可用平方数的个数
  47. int ans[][];
  48. int anum = ; //答案个数
  49. int M, N;
  50. int i, j, k;
  51.  
  52. for(i = ; i < ; i++)
  53. {
  54. bisquare[i] = MAXN;
  55. }
  56.  
  57. fscanf(in, "%d %d", &N, &M);
  58.  
  59. for(i = ; i <= M; i++)
  60. {
  61. for(j = ; j <= M; j++)
  62. {
  63. bisquare[binum] = i * i + j * j;
  64. binum++;
  65. }
  66. }
  67.  
  68. qsort(bisquare, binum, sizeof(bisquare[]), cmp);
  69.  
  70. //去掉相同的平方和数
  71. int numt = binum;
  72. for(i = ; i < numt; i++)
  73. {
  74. if(bisquare[i] == bisquare[i + ])
  75. {
  76. bisquare[i] = MAXN;
  77. binum--;
  78. }
  79. }
  80. qsort(bisquare, numt, sizeof(bisquare[]), cmp);
  81.  
  82. int flag;
  83. //对所有间隔大小, 所有起始位搜索
  84. for(i = ; i <= /*M * M * 2*/; i++)
  85. {
  86. for(j = ; j < && j < binum - N + ; j++)
  87. {
  88. flag = ;
  89. int m = j;
  90. for(k = ; k < N; k++)
  91. {
  92. if(BinarySearch(bisquare, j + , binum - , bisquare[j] + k * i) == )
  93. {
  94. flag = ;
  95. break;
  96. }
  97.  
  98. }
  99. if(flag == )
  100. {
  101. ans[anum][] = bisquare[j];
  102. ans[anum][] = i;
  103. anum++;
  104. }
  105. }
  106. }
  107.  
  108. if(anum > )
  109. {
  110. for(i = ; i < anum; i++)
  111. {
  112. fprintf(out, "%d %d\n", ans[i][], ans[i][]);
  113. }
  114. }
  115. else
  116. {
  117. fprintf(out, "NONE\n");
  118. }
  119. return ;
  120. }

----------------------------------

看了答案  用了一种更NB的查找方法  直接建一个0,1大数组 有该数设为1 没有设为0 直接读取即可 改为这种常数时间的查找后 时间又是呈数量级式的下降了

间隔的上限为 M * M * 2 / (N - 1)   首元素的循环条件为 bisquare[j] + (N - 1) * 当前间隔 <= M * M * 2 整体修改后 计算时间均在2s以内

最终版完整代码:

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <math.h>
  4.  
  5. #define MAXN 200000
  6. int cmp(const void *va, const void *vb)
  7. {
  8. return (*(int *)va) - (*(int *)vb);
  9. }
  10.  
  11. int BinarySearch(int * T, int left, int right, int x)
  12. {
  13.  
  14. int l = left, r = right;
  15. while(l < r)
  16. {
  17. int m = (l + r) / ;
  18. int aa= T[m];
  19. if(T[m] == x)
  20. {
  21. return ;
  22. }
  23. else if(T[m] < x)
  24. {
  25. l = m + ;
  26. }
  27. else
  28. {
  29. r = m - ;
  30. }
  31. }
  32. if(T[l] == x)
  33. {
  34. return ;
  35. }
  36. return ;
  37. }
  38.  
  39. int main()
  40. {
  41.  
  42. FILE *in, *out;
  43. in = fopen("ariprog.in", "r");
  44. out = fopen("ariprog.out", "w");
  45.  
  46. int bisquare[]; //存储所有可以用的平方数
  47. int binum = ; //存储可用平方数的个数
  48. int ans[][];
  49. int is[] = {};
  50. int anum = ; //答案个数
  51. int M, N;
  52. int i, j, k;
  53.  
  54. for(i = ; i < ; i++)
  55. {
  56. bisquare[i] = MAXN;
  57. }
  58.  
  59. fscanf(in, "%d %d", &N, &M);
  60.  
  61. for(i = ; i <= M; i++)
  62. {
  63. for(j = ; j <= M; j++)
  64. {
  65. if(is[i * i + j * j] == ) //用is判断可以去掉重复的数字
  66. {
  67. bisquare[binum] = i * i + j * j;
  68. binum++;
  69. is[i * i + j * j] = ;
  70. }
  71. }
  72. }
  73.  
  74. qsort(bisquare, binum, sizeof(bisquare[]), cmp);
  75.  
  76. int flag;
  77. int upperb = M * M * / (N - );
  78. //对所有间隔大小, 所有起始位搜索
  79. for(i = ; i <= upperb; i++)
  80. {
  81. for(j = ; bisquare[j] + (N - ) * i <= M * M * ; j++)
  82. {
  83. flag = ;
  84. int m = j;
  85. for(k = ; k < N; k++)
  86. {
  87. if(is[bisquare[j] + k * i] == )
  88. {
  89. flag = ;
  90. break;
  91. }
  92.  
  93. }
  94. if(flag == )
  95. {
  96. ans[anum][] = bisquare[j];
  97. ans[anum][] = i;
  98. anum++;
  99. }
  100. }
  101. }
  102.  
  103. if(anum > )
  104. {
  105. for(i = ; i < anum; i++)
  106. {
  107. fprintf(out, "%d %d\n", ans[i][], ans[i][]);
  108. }
  109. }
  110. else
  111. {
  112. fprintf(out, "NONE\n");
  113. }
  114. return ;
  115. }

【USACO】ariprog的更多相关文章

  1. POJ 1986 Distance Queries / UESTC 256 Distance Queries / CJOJ 1129 【USACO】距离咨询(最近公共祖先)

    POJ 1986 Distance Queries / UESTC 256 Distance Queries / CJOJ 1129 [USACO]距离咨询(最近公共祖先) Description F ...

  2. 1642: 【USACO】Payback(还债)

    1642: [USACO]Payback(还债) 时间限制: 1 Sec 内存限制: 64 MB 提交: 190 解决: 95 [提交] [状态] [讨论版] [命题人:外部导入] 题目描述 &quo ...

  3. 1519: 【USACO】超级书架

    1519: [USACO]超级书架 时间限制: 1 Sec 内存限制: 64 MB 提交: 1735 解决: 891 [提交] [状态] [讨论版] [命题人:外部导入] 题目描述 Farmer Jo ...

  4. Java实现【USACO】1.1.2 贪婪的礼物送礼者 Greedy Gift Givers

    [USACO]1.1.2 贪婪的礼物送礼者 Greedy Gift Givers 题目描述 对于一群要互送礼物的朋友,你要确定每个人送出的礼物比收到的多多少(and vice versa for th ...

  5. 【CPLUSOJ】【USACO】【差分约束】排队(layout)

    [题目描述] Robin喜欢将他的奶牛们排成一队.假设他有N头奶牛,编号为1至N.这些奶牛按照编号大小排列,并且由于它们都很想早点吃饭,于是就很可能出现多头奶牛挤在同一位置的情况(也就是说,如果我们认 ...

  6. 【USACO】Dining

    [题目链接] [JZXX]点击打开链接 [caioj]点击打开链接 [算法] 拆点+网络流 [代码] #include<bits/stdc++.h> using namespace std ...

  7. 【USACO】Optimal Milking

    题目链接 :        [POJ]点击打开链接        [caioj]点击打开链接 算法 : 1:跑一遍弗洛伊德,求出点与点之间的最短路径 2:二分答案,二分”最大值最小“ 3.1:建边,将 ...

  8. 【USACO】 Balanced Photo

    [题目链接] 点击打开链接 [算法] 树状数组 [代码] #include<bits/stdc++.h> using namespace std; int i,N,ans,l1,l2; ] ...

  9. 【USACO】 Balanced Lineup

    [题目链接] 点击打开链接 [算法] 这是一道经典的最值查询(RMQ)问题. 我们首先想到线段树.但有没有更快的方法呢?对于这类问题,我们可以用ST表(稀疏表)算法求解. 稀疏表算法.其实也是一种动态 ...

随机推荐

  1. 蝙蝠算法-python实现

    BAIndividual.py import numpy as np import ObjFunction class BAIndividual: ''' individual of bat algo ...

  2. BZOJ3229 石子合并

    Description 在一个操场上摆放着一排N堆石子.现要将石子有次序地合并成一堆.规定每次只能选相邻的2堆石子合并成新的一堆,并将新的一堆石子数记为该次合并的得分. 试设计一个算法,计算出将N堆石 ...

  3. Linux X Window System运行原理和启动过程

    本文主要说明X Window System的基本运行原理,其启动过程,及常见的跨网络运行X Window System. 一) 基本运行原理 X Window System采用C/S结构,但和我们常见 ...

  4. POJ1328Radar Installation(区间点覆盖问题)

    Radar Installation Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 68597   Accepted: 15 ...

  5. UIScrollview自动布局,UIScrollviewAutolayoutDemo

    参考文档:http://www.cocoachina.com/ios/20150104/10810.html UIScrollviewAutolayoutDemo地址:http://pan.baidu ...

  6. 我在 impress.js 中学到的小套路

    我在 impress.js 中学到的小套路 写在开篇 作为了一个自学 JavaScript 才一个月的新手,前几天“妄图”研究 jQuery-3.1.0 源码,结果自然是被虐得死去活来.机缘巧合之下, ...

  7. DEDECMS全版本gotopage变量XSS ROOTKIT 0DAY

    影响版本: DEDECMS全版本 漏洞描叙: DEDECMS后台登陆模板中的gotopage变量未效验传入数据,导致XSS漏洞. \dede\templets\login.htm 65行左右 < ...

  8. struts2拦截器interceptor的三种配置方法

    1.struts2拦截器interceptor的三种配置方法 方法1. 普通配置法 <struts> <package name="struts2" extend ...

  9. cocos进阶教程(2)多分辨率支持策略和原理

    cocos2d-x3.0API常用接口 Director::getInstance()->getOpenGLView()->setDesignResolutionSize() //设计分辨 ...

  10. PPTP服务器配置选项详解

    导读 PPTP服务器配置文件的格式与其它许多Unix程序相似,每一行包含一项配置内容,以配置选项名称开始,后面紧跟参数值或者关键字,它们之间用空格分隔.在读取配置文件时,pptpd进程将忽略空行和每一 ...