FZU 1492 地震预测(模拟链表)(技巧题)
2017-03-29 19:22
190 查看
地震预测
Problem Description怀特先生是一名研究地震的科学家,最近他发现如果知道某一段时间内的地壳震动能量采样的最小波动值之和,可以有效地预测大地震的发生。
假设已知一段时间的n次地壳震动能量的采样值为a1,a2,…an,那么第i 次采样的最小波动值为min{|ai-aj| | i<j<=n},即第i 次采样的最小波动值是其后n-i次采样值与第i次采样值之差的绝对值中最小的值,特别地,第n次采样的最小波动值为an。
请编写一个程序计算这n次采样的最小波动值之和。
Input
本题有多组输入数据,你必须处理到EOF为止
输入数据第一行有一个数n(1<=n<=105) ,表示采样的次数。
第二行有n个整数,表示n次地壳震动能量的采样值a1,a2,…an (0<=ai<=107 )。
Output
输出n次采样的最小波动值之和。
Sample Input
4
2 0 3 10
Sample Output
21
ps:题意很容易懂,就是一般的方法直接就TLE了。。。
分析:
题目要求的是每一个数与它后面的数的最小差值之和,所以我们可以先把给定的数字从小到大排序(要先记录下每一个数原先的位置);
因为有序,所以最小差值肯定是减去左边或者右边的值,但是如果是单纯的数组的话,它的左边或右边不一定是它原顺序后面的数,
因此我们可以数组模拟链表(记录下排序后每一个数的位置),从原顺序的第一个数开始计算,计算完后就将这个数字从链表中删除,并更新链表中它的前一位的next和后一位的pre,具体详见代码
代码:
#include<stdio.h> #include<math.h> #include<algorithm> using namespace std; #define maxn 100000+10 #define min(a,b) (a<b?a:b) const int inf=2000000000; struct node { int x,po; }num[maxn]; int pre[maxn],next[maxn],c[maxn],list[maxn]; int n; bool cmp(node a,node b) { return a.x<b.x; } int Find(int i) { int x1=-inf,x2=inf; if(pre[i]>=1) x1=list[pre[i]]; if(next[i]<=n) x2=list[next[i]]; return min(abs(list[i]-x1),abs(list[i]-x2)); } int main() { while(~scanf("%d",&n)) { for(int i=1;i<=n;i++) { scanf("%d",&num[i].x); num[i].po=i; } int ed=num .x; sort(num+1,num+n+1,cmp); for(int i=1;i<=n;i++) { list[i]=num[i].x; c[num[i].po]=i; pre[i]=i-1; next[i]=i+1; } int ans=0; for(int i=1;i<n;i++) { ans+=Find(c[i]); pre[next[c[i]]]=pre[c[i]];//更新链表 next[pre[c[i]]]=next[c[i]];// } printf("%d\n",ans+ed); } return 0; }
总结:感觉真是很有意思的一道题,因为一般的想法的话肯定是一个一个找最小值,这种通过链表先排序后找的方法很巧妙啊。
以前也从来没有用过链表写过题,现在忽然发现链表很强大啊。
相关文章推荐
- FZU 1492 地震预测(模拟链表)(技巧题)
- FZU 1492 地震预测(模拟链表)(技巧题)
- FZU 1492 地震预测(模拟链表)(技巧题)
- FZU 1492 地震预测(模拟链表)(技巧题)
- FZU 1492 地震预测(模拟链表)(技巧题)
- FZU 1492 地震预测(模拟链表)(技巧题)
- FZU 1492 地震预测(模拟链表)(技巧题)
- FZU 1492 地震预测(模拟链表)(技巧题)
- FZU 1492 地震预测(模拟链表)(技巧题)
- FZU 1492 地震预测(模拟链表)(技巧题)
- FZU 1492 地震预测(模拟链表)(技巧题)
- FZU 1492 地震预测(模拟链表)(技巧题)
- FZU 1492 地震预测(模拟链表)(技巧题)
- FZU 1492 地震预测(模拟链表的应用)(Java实现)
- FZU - 1492(Problem 1492 地震预测)
- FZU 1893 (模拟内存分配算法 涉及链表等 13.12.03)
- 使用链表来模拟栈(java实现)
- FZU 2203 单纵大法好(模拟、二分)
- 技巧:在 C/C++中如何构造通用的对象链表
- codeforces 792B——Counting-out Rhyme(数组模拟链表)