输入 : N  M

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

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

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

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

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

#include <stdio.h>
#include <stdlib.h>
#include <math.h> #define MAXN 200000
int cmp(const void *va, const void *vb)
{
return (*(int *)va) - (*(int *)vb);
} int find(int * bisquare, int binum, int num)
{
int i;
for(i = 0; i < binum; i++)
{
if(bisquare[i] == num)
return 1;
}
return 0;
} int main()
{
FILE *in, *out;
in = fopen("ariprog.in", "r");
out = fopen("ariprog.out", "w"); int bisquare[40000]; //存储所有可以用的平方数
int binum = 0; //存储可用平方数的个数
int ans[10000][2];
int anum = 0; //答案个数
int gap[25]; //存储间隔
int M, N;
int i, j, k; for(i = 0; i < 40000; i++)
{
bisquare[i] = MAXN;
} fscanf(in, "%d %d", &N, &M); for(i = 0; i <= M; i++)
{
for(j = 0; j <= M; j++)
{
bisquare[binum] = i * i + j * j;
binum++;
}
} qsort(bisquare, binum, sizeof(bisquare[0]), cmp); //去掉相同的平方和数
int numt = binum;
for(i = 0; i < numt; i++)
{
if(bisquare[i] == bisquare[i + 1])
{
bisquare[i] = MAXN;
binum--;
}
}
qsort(bisquare, numt, sizeof(bisquare[0]), cmp); int flag;
//对所有间隔大小, 所有起始位搜索
for(i = 1; i <= M * M * 2; i++)
{
for(j = 0; j < binum - N + 1; j++)
{
flag = 1;
for(k = 1; k < N; k++)
{
if(find(bisquare, binum, bisquare[j] + k * i) == 0)
{
flag = 0;
break;
}
}
if(flag == 1)
{
ans[anum][0] = bisquare[j];
ans[anum][1] = i;
anum++;
}
}
} if(anum > 0)
{
for(i = 0; i < anum; i++)
{
fprintf(out, "%d %d\n", ans[i][0], ans[i][1]);
}
}
else
{
fprintf(out, "NONE\n");
} return 0; }

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

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

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

修改的部分代码:

    for(i = ; i < binum - ; i++)
{
gap[i] = bisquare[i + ] - bisquare[i];
}
//..................
//if(find(bisquare, binum, bisquare[j] + k * i) == 0)
//{
// flag = 0;
// break;
//}
int inter = ;
while(inter < i && m <= binum - )
{
inter = inter + gap[m];
m++;
}
if(inter != i)
{
flag = ;
break;
}
//....................

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

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

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

int BinarySearch(int * T, int left, int right, int x)
{ int l = left, r = right;
while(l < r)
{
int m = (l + r) / ;
int aa= T[m];
if(T[m] == x)
{
return ;
}
else if(T[m] < x)
{
l = m + ;
}
else
{
r = m - ;
}
}
if(T[l] == x)
{
return ;
}
return ;
}

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

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

#include <stdio.h>
#include <stdlib.h>
#include <math.h> #define MAXN 200000
int cmp(const void *va, const void *vb)
{
return (*(int *)va) - (*(int *)vb);
} int BinarySearch(int * T, int left, int right, int x)
{ int l = left, r = right;
while(l < r)
{
int m = (l + r) / ;
int aa= T[m];
if(T[m] == x)
{
return ;
}
else if(T[m] < x)
{
l = m + ;
}
else
{
r = m - ;
}
}
if(T[l] == x)
{
return ;
}
return ;
} int main()
{
FILE *in, *out;
in = fopen("ariprog.in", "r");
out = fopen("ariprog.out", "w"); int bisquare[]; //存储所有可以用的平方数
int binum = ; //存储可用平方数的个数
int ans[][];
int anum = ; //答案个数
int M, N;
int i, j, k; for(i = ; i < ; i++)
{
bisquare[i] = MAXN;
} fscanf(in, "%d %d", &N, &M); for(i = ; i <= M; i++)
{
for(j = ; j <= M; j++)
{
bisquare[binum] = i * i + j * j;
binum++;
}
} qsort(bisquare, binum, sizeof(bisquare[]), cmp); //去掉相同的平方和数
int numt = binum;
for(i = ; i < numt; i++)
{
if(bisquare[i] == bisquare[i + ])
{
bisquare[i] = MAXN;
binum--;
}
}
qsort(bisquare, numt, sizeof(bisquare[]), cmp); int flag;
//对所有间隔大小, 所有起始位搜索
for(i = ; i <= /*M * M * 2*/; i++)
{
for(j = ; j < && j < binum - N + ; j++)
{
flag = ;
int m = j;
for(k = ; k < N; k++)
{
if(BinarySearch(bisquare, j + , binum - , bisquare[j] + k * i) == )
{
flag = ;
break;
} }
if(flag == )
{
ans[anum][] = bisquare[j];
ans[anum][] = i;
anum++;
}
}
} if(anum > )
{
for(i = ; i < anum; i++)
{
fprintf(out, "%d %d\n", ans[i][], ans[i][]);
}
}
else
{
fprintf(out, "NONE\n");
}
return ;
}

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

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

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

最终版完整代码:

#include <stdio.h>
#include <stdlib.h>
#include <math.h> #define MAXN 200000
int cmp(const void *va, const void *vb)
{
return (*(int *)va) - (*(int *)vb);
} int BinarySearch(int * T, int left, int right, int x)
{ int l = left, r = right;
while(l < r)
{
int m = (l + r) / ;
int aa= T[m];
if(T[m] == x)
{
return ;
}
else if(T[m] < x)
{
l = m + ;
}
else
{
r = m - ;
}
}
if(T[l] == x)
{
return ;
}
return ;
} int main()
{ FILE *in, *out;
in = fopen("ariprog.in", "r");
out = fopen("ariprog.out", "w"); int bisquare[]; //存储所有可以用的平方数
int binum = ; //存储可用平方数的个数
int ans[][];
int is[] = {};
int anum = ; //答案个数
int M, N;
int i, j, k; for(i = ; i < ; i++)
{
bisquare[i] = MAXN;
} fscanf(in, "%d %d", &N, &M); for(i = ; i <= M; i++)
{
for(j = ; j <= M; j++)
{
if(is[i * i + j * j] == ) //用is判断可以去掉重复的数字
{
bisquare[binum] = i * i + j * j;
binum++;
is[i * i + j * j] = ;
}
}
} qsort(bisquare, binum, sizeof(bisquare[]), cmp); int flag;
int upperb = M * M * / (N - );
//对所有间隔大小, 所有起始位搜索
for(i = ; i <= upperb; i++)
{
for(j = ; bisquare[j] + (N - ) * i <= M * M * ; j++)
{
flag = ;
int m = j;
for(k = ; k < N; k++)
{
if(is[bisquare[j] + k * i] == )
{
flag = ;
break;
} }
if(flag == )
{
ans[anum][] = bisquare[j];
ans[anum][] = i;
anum++;
}
}
} if(anum > )
{
for(i = ; i < anum; i++)
{
fprintf(out, "%d %d\n", ans[i][], ans[i][]);
}
}
else
{
fprintf(out, "NONE\n");
}
return ;
}

【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 学习5--matplotlib画图实践

    ### Python的强大很大一部分原因在于,它提供有很多已经写好的,可以现成用的对象 学习参考: http://www.cnblogs.com/vamei/archive/2013/01/30/28 ...

  2. JavaScript parser

    JavaScript parser 和上面功能有点像,折叠JS代码,快速找到JS中类,方法的工具

  3. sixsix团队“餐站”应用M2阶段发布报告

    一.新功能 客户端 搜索功能 我们在M2中实现了对地点的搜索菜品,可以直接在主页页面中的输入框输入用户喜欢的菜品,系统将返回与对应关键字所对应的选择,更加高效直观的满足客户的口味. 菜品图片加载 我们 ...

  4. Integer.valueOf(String) 方法之惑

    本文由 ImportNew - 靳禹 翻译自 stackoverflow.欢迎加入翻译小组.转载请见文末要求. 有个仁兄在 StackOverflow 上发起了一个问题,是这么问的: “ 我被下面的代 ...

  5. 第二部分 Mongodb增删改查

    学习内容:1.mongodb增加操作2.mongodb删除操作3.mongodb查询操作增删改查的高级应用Capped Collection(固定集合)GridFS 大文件上传或下载 1: inser ...

  6. hdu 2111 Saving HDU

    解题思路: 首先做本题,要清楚题意的要求. 1.读取数据到结构体数组中,然后按其价值降序(价值最大的放在最上面). 2.比较给定的M (包裹容量),如果大于当前宝物的体积,则计算总价值+= 宝物的总价 ...

  7. truncate的用法

    truncate是文件处理中的截断函数,今天是有个需求改动了json中的某个值,然后用改动后的值去覆盖之前的数据,这个方法有很多,比如边读边写,然后使用os模块替换,这个适合用于在程序和文件都在同一个 ...

  8. CentOS6.5安装iftop

    iftop这个小工具是Linux和unix下的top命令升级版,功能相对较强,界面易懂.今天安装了CentOS6.5的最新版,装个小工具检查下系统运行性能. 官网:http://www.ex-parr ...

  9. [整理]通过AngularJS directive对bootstrap日期控件的的简单包装

    最近项目上了AngularJS,而原来使用的日期控件的使用方式也需要改变,于是开始了倒腾,看了官方的例子,可以使用AngularJS的directive做简单的处理,这样在html里直接使用申明的的形 ...

  10. 几款web开发常用jquery特效代码

    特效网:http://www.xwcms.net  1.图片拖动特效http://www.xwcms.net/js/tpdm/32946.html2.弹出层焦点图特效:http://www.xwcms ...