ACM中的几个小技巧(离散化,尺取法,数据预处理)
来源:互联网 发布:网站平台优化方案 编辑:程序博客网 时间:2024/03/28 21:57
离散化
使用STL算法离散化:
思路:先排序,再删除重复元素,然后就是索引元素离散化后对应的值。
假定待离散化的序列为a[n],b[n]是序列a[n]的一个副本,则对应以上三步为:
sort(sub_a,sub_a+n);int size=unique(sub_a,sub_a+n)-sub_a;//size为离散化后元素个数for(i=0;i<n;i++)a[i]=lower_bound(sub_a,sub_a+size,a[i])-sub_a + 1;//k为b[i]; ```经离散化后对应的值对于第3步,若离散化后序列为0, 1, 2, ..., size - 1则用lower_bound,从1, 2, 3, ..., size则用upper_bound,其中lower_bound返回第1个不小于b[i]的值的指针,而upper_bound返回第1个大于b[i]的值的指针,当然在这个题中也可以用lower_bound然后再加1得到与upper_bound相同结果,两者都是针对以排好序列。使用STL离散化大大减少了代码量且结构相当清晰。**尺取法**给定长度为n的数列整数a0,a1,a2,a3 ..... an-1以及整数S。求出综合不小于S的连续子序列的长度的最小值。如果解不存在,则输出0。 10 < n< 10 ^ 50 < a i < 10^4 S<10^8这里我们拿第一组测试数据举例子,即 n=10, S = 15, a = {5,1,3,5,10,7,4,9,2,8}![](http://images.cnitblog.com/blog/597004/201408/291224259702079.jpg)1.初始化左右端点2.不断扩大右端点,直到满足条件3.如果第二步中无法满足条件,则终止,否则更新结果4.将左端点扩大1,然后回到第二步例题:poj 3320 尺取法+Map``#include <map>#include <queue>#include <cmath>#include <cstdio>#include <cstring>#include <iostream>#include <algorithm>#define maxn 100005#define MOD 1000000007#define inf 0x3f3f3f3ftypedef long long ll;using namespace std;int n,m,k;int a[maxn];int main(){ while(~scanf("%d",&n)){ map<int,int>Hash,cnt; for(int i = 0;i<n;i++){ scanf("%d",a+i); Hash[a[i]]++; } int tot = Hash.size(); int tag = 1; int s = 0,e = 0; int ans = inf; while(tag){ while(cnt.size()<tot && e<n) cnt[a[e++]]++; if(cnt.size()<tot) {tag=0;break;} ans = min(ans,e-s); cnt[a[s]]--; if(cnt[a[s]]==0) cnt.erase(a[s]); s++; } printf("%d\n",ans); } return 0;}
数据预处理
以HDU 5073 鞍山D为例。
主要是针对区间的求和,平方这类的预处理
#include<cstdio>#include<cstring>#include<iostream>#include<algorithm>#define maxn 51000using namespace std;double sum1,sum2;double pos[maxn];int main(){ int T; scanf("%d",&T); while(T--){ int n,k; scanf("%d%d",&n,&k); for(int i = 1;i<=n;i++) scanf("%lf",pos+i); if(n==k){puts("0");continue;} sort(pos+1,pos+1+n); sum1 = sum2 = 0; int m = n-k; for(int i = 1;i<m;i++){ sum1 += pos[i]; sum2 += pos[i] * pos[i]; } double ans = 1e100; for(int i = m;i<=n;i++){ sum1 += pos[i]; sum2 += pos[i]*pos[i]; double mid = sum1 / m; double tmp = sum2 + m*mid*mid - 2*mid*sum1; ans = min(ans,tmp); sum1 -= pos[i-m+1]; sum2 -= pos[i-m+1] * pos[i-m+1]; } printf("%.12f\n",ans); } return 0;}
0 0
- ACM中的几个小技巧(离散化,尺取法,数据预处理)
- ACM常用的解题技巧:尺取法
- ACM常用的解题技巧:尺取法
- 数据预处理之“分类”数据离散化
- 数据预处理之“分类”数据离散化
- 数据预处理之数据离散化
- WinForm中的几个小技巧
- ACM常用技巧之尺取法--POJ3061/3320/2739/2100
- ACM算法:尺取法
- nyoj 133 子序列(尺取法+离散化)
- 【poj】3320 Jessica's Reading Problem 尺取法+离散化
- nyoj 133 子序列 (离散化+尺取法)
- nyoj 133 子序列 (离散化+尺取法)
- 4.1-4.3 数据预处理-清洗-变换-离散化
- ACM做题过程中的小技巧
- asp.net 2.0中的几个小技巧
- c语言中的几个小技巧
- Rational画类图中的几个小技巧
- Ubuntu9.10安装Qt环境
- Mac——开启关闭隐藏文件
- HDOJ 1069 Monkey and Banana
- iOS开发中Objective-C 对 URL的URLEncode(编码)与URLDecode(解码)
- flexlm license许可证管理
- ACM中的几个小技巧(离散化,尺取法,数据预处理)
- jsp表达式
- ubuntu 启动问题解决
- UNIX网络编程中RST分节总结
- eclipse生成.apk文件安装到手机
- 创业公司
- 大白话系列之C#委托与事件讲解(二)
- 关于uploadify导致chrome页面崩溃
- Maven环境快速搭建。