怀特先生是一名研究地震的科学家,最近他发现如果知道某一段时间内的地壳震动能量采样的最小波动值之和,可以有效地预测大地震的发生。
假设已知一段时间的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 )。
输出n次采样的最小波动值之和。
4 2 0 3 10
21
map的用法参见http://blog.sina.com.cn/s/blog_49c5866c0100eyh0.html
这题是方法说白了就是从后往前。比如题目的数据2 0 3 10sum为和3和10最后两位直接处理完按照大小形成一个虚拟3 10 sum=170插入到这个序列中 0 3 10比较0的前后减去0的绝对值谁比较小,取小的那个。 取3 sum=20然后放入2 形成0 2 3 10 比较前后2-0>3-2 取1 sum=21使用map的原因是由于map有序。。。。。
#include<stdio.h> #include<iostream> #include<string.h> #include<math.h> #include<cmath> #include<vector> #include<map> using namespace std; map<int,int>dd; int main() {int a[100100]; int n; while(scanf("%d",&n)!=-1) { int i; for(i=0;i<n;i++) { scanf("%d",&a[i]); } dd[a[n-1]]=n-1; dd[a[n-2]]=n-2; int sum=a[n-1]+abs(a[n-1]-a[n-2]); for(int i=n-3;i>=0;i--) { if(!dd.count(a[i])) { dd[a[i]]=i; } else continue; map<int,int>::iterator t=dd.find(a[i]); map<int,int>::iterator next=++t; map<int,int>::iterator fron; t--; if(t!=dd.begin()) { fron=--t; t++; } else { fron=t; } int minn; if(next==dd.end()) { minn=t->first-fron->first; } else if(t==dd.begin()) { minn=next->first-t->first; } else { minn=next->first-t->first; if(minn>(t->first-fron->first)) minn=t->first-fron->first; //minn=min(next->first-t->first,t->first-fron->first); } sum+=minn; } printf("%d\n",sum); dd.clear(); } return 0; }

2885

被折叠的 条评论
为什么被折叠?



