hdu 4961 Boring Sum (思维 哈希 扫描)
2024-09-23 08:04:27
题意:给你一个数组,让你生成两个新的数组,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 ;
}
最新文章
- svg.js教程及使用手册详解(一)
- JavaScript检测文件上传的类型与大小
- Java调用脚本
- SQL GROUP BY 后排序
- 配置文件,环境配置和war报分离,方便生产更改
- msyql判断记录是否存在的三种方法
- get top k elements of the same key in hive
- jQuery 代码的层定位滑动动画效果
- drupal7为admin/config页面添加自己开发的模块
- 预加载(图片,css ,js)
- Nosql简介 Redis,Memchche,MongoDb的区别
- Map 遍历分析
- 删除API
- Hadoop之搭建完全分布式运行模式
- 微信小程序笑话小程序实践开发学习
- 编译安装redis4.0
- NYOJ37-回文字符串(dp)
- python之间的基础
- lower_bound函数与upper_bound函数
- jQuery对象的操作