题目链接

题意:给你一个数组,让你生成两个新的数组,A要求每个数如果能在它的前面找个最近的一个是它倍数的数,那就变成那个数,否则是自己,C是往后找,输出交叉相乘的和

分析:

这个题这种做法是O(n*sqrt(n))的复杂度,极限数据绝对会超时,但是这个题的数据有点水,所以可以过。

用vis【i】数组表示离数字 i  最近的倍数那个数在a【】中的位置,因为所有数字范围在1--100000所以可行 ,正着扫一遍,每次找到当前的数的除数,同时把除数覆盖位置,把 /除数 的数也覆盖位置。

倒着也是一样,找的是离这个数最近的倍数数字,然后相乘就行了。

 #include <iostream>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <cmath>
#include <algorithm>
#define LL __int64
const int maxn = +;
using namespace std;
LL a[maxn], pre[maxn], af[maxn], vis[maxn], sum; int main()
{
int n, i, j, tmp;
while(~scanf("%d", &n) && n)
{
memset(af, , sizeof(af));
memset(pre, , sizeof(pre));
memset(vis, , sizeof(vis));
for(i = ; i <= n; i++)
scanf("%I64d", &a[i]);
for(i = ; i <= n; i++)
{
if(vis[a[i]])
pre[i] = a[vis[a[i]]];
else
pre[i] = a[i];
tmp = (int)sqrt(a[i]);
for(j = ; j <= tmp; j++)
if(a[i]%j==)
{
vis[j] = i;
vis[a[i]/j] = i; //一定不要忘了sqrt后面还有这个数的除数
}
} memset(vis, , sizeof(vis));
for(i = n; i >= ; i--)
{
if(vis[a[i]])
af[i] = a[vis[a[i]]];
else
af[i] = a[i];
tmp = (int)sqrt(a[i]);
for(j = ; j <= tmp; j++)
if(a[i]%j==)
{
vis[j] = i;
vis[a[i]/j] = i;
}
}
sum = ;
for(i = ; i <= n; i++)
sum += pre[i]*af[i];
printf("%I64d\n", sum);
}
return ;
}

最新文章

  1. svg.js教程及使用手册详解(一)
  2. JavaScript检测文件上传的类型与大小
  3. Java调用脚本
  4. SQL GROUP BY 后排序
  5. 配置文件,环境配置和war报分离,方便生产更改
  6. msyql判断记录是否存在的三种方法
  7. get top k elements of the same key in hive
  8. jQuery 代码的层定位滑动动画效果
  9. drupal7为admin/config页面添加自己开发的模块
  10. 预加载(图片,css ,js)
  11. Nosql简介 Redis,Memchche,MongoDb的区别
  12. Map 遍历分析
  13. 删除API
  14. Hadoop之搭建完全分布式运行模式
  15. 微信小程序笑话小程序实践开发学习
  16. 编译安装redis4.0
  17. NYOJ37-回文字符串(dp)
  18. python之间的基础
  19. lower_bound函数与upper_bound函数
  20. jQuery对象的操作

热门文章

  1. JDBC增删改查
  2. 团队博客作业Week1 Team Homework #3软件工程在北航
  3. Eclipse启动的时候窗口一闪就关的解决办法(转)
  4. android 中怎么控制checkbox中文本与左侧box的距离
  5. 巨大bug
  6. C#笔记1:异常
  7. request 路径随笔
  8. SQL Server性能常用语句
  9. C#快速排序算法基础入门篇
  10. 【娱乐】高端小游戏Manufactoria