第一讲
C语言,C++,jave
• 输入
while(~scanf("%d",&n)){}
scanf("%[^
]",s);//读入一行
scanf("[0-9]",s);//读入字符串0-9 读到不是0-9停下 ^不读0-9
sort(a,a+n,cmp)//no cmp 默认从小到大 o(lognn)
a.begin(),a.end()
int cmp(int x,int y)
{
return y>x;
}
//using namespace std
unique(a,a+n)//
得到数组中不重复的元素
int m=unique(a,a+n)-a;//保证数组有序才能用unique o(n)
Jave 高精度 进制转换 时限:2倍/3倍
Import jave.io.*;
Import jave.util.*;
Public class main
{
}
Hasnext()
Nextint()
Next()//读入字符串
Nextline()
Nextbiginteger()
System.out.printin()
DecimalFormat
• 二分
左右两个部分 0(lognn)
Int bi(int l,int r)
{
While(r-l>1)
{
Int mid=(l+r)/2;
If(check(mid)) l=mid;
Else R=mid;
}
Return mid;
}
//lower.bound
Eg2: 找上标和下标
Upper_bound(a,a+n,b);
Lower_bound(a,a+n,b);//得先排序
Eg3:给定长度为你=n的数组,从每一个里面选取一个值。问有多少种方法使四个值和为0.n<4000(*)
加起来两个n*n 然后枚举 o(n*n*logn)
Eg3:给定一个2维数据,上<下,左<右,查找x(*)
1每一行或每一列(小的那个)二分查找 o(min(n,m)*logn)
2从右上角来查找 大往下,小往左 o(m+n)
Eg4:给定数组 找到一个位置使得他相邻的两个位置的值都比当前位置小。A[0]=a[n+1]=负无穷(**)
1简化为差分数组
2mid&mid+1
Eg5:可能被旋转的单调递增数组直接,求最小值([1 2 3 4 5]-->[4 5 1 2 3]整体右移后面的拿到前面来)(***)
直接中间来
二分答案(最小值最大 最大值最小)
Eg1: n个石头 给了到起点的距离。问要去掉n个中m个使其间距值最小值最大(**)
知道间距 判断去m个使任意两个间距大于等于间距 二分答案
Eg2:每件衣服有一定水量,有烘干机可以烘干一件衣服,1min可以烘干k件衣服。每件衣服每分钟可以自动蒸发一滴水,用烘干机使不蒸发。最少时间(**)
给时间看是否能烘干 先烘干最湿的 二分???
Eg3: n个物品,每个物品有属性A&B 选k个物品,使a值之和除以b值之和最大 n<10^6(**)//零一分数规划
Sum(a) / sum(b)>=mid--> sum(a)-sum(b)*mid>=0
每次mid重新排序选取前k个
数据太大卡掉了
采用函数 nth_element(a,a+n,k) 把前k大的值放在了前k个位置但不是排序 o(n)//快排!!了解一下这个函数
• 三分
类似二分定义left right
mid=(l+r)/2
midmid=(m+r)/2
If mid 靠近极值点 r=midmid
Else l=mid
(L+l+r)/3
(l+R+R)/3
L+(R-L)*0.382
L+(R-L)*0.618
Eg1: n个开口向上的二次函数,max中的最小值(**)
//还是单峰函数???
Eg2:poor为这个区间和的绝对值 weakness等于所有区间最大的poorness 求x使得,序列A全部减x后weakness最小(***)
x增大weakness减小--> x减小weakness增大
Eg3:给整数x 求(x+x^2+……+x^y)%p; x,y<10^9;p>10^9(***)
等比数列公式&求逆元??
x也可换为矩阵a
(x+x^2+x^3)*(1+x^3)
Eg4: n为大整数,求™的乘积,复杂度小于0(n^2)
T(n)=4T(n/2)+o(n)
T(n)=????
Eg5: n个物品体积和价值 容量v 选取不超过k个物品 n<500 v<10000(****)
WSQ二分加一个x去控制物品数量
Eg6:n个村庄 给出每个村庄的坐标。要在这条直线上选k个地方建雕塑,使得每个村庄到离其最近的雕塑的距离的和最小,输出最小的和 n<1e5(*****)
• 问题
○ 测试a java
○ 测试c
○ 测试d 二分答案
○ 测试e 三分
○ 测试g
○ 测试j floyd