zoukankan      html  css  js  c++  java
  • #寒假集训[20200111-1]

    scanf正则表达式

    scanf("%s",%[0-9])//读入的为0-9的字符,读到非0-9时即停止
    scanf("%s",&[^
    ])//加^意味着不读后面的字符,所以为读入知道读到换行符
    

    (常用函数:m=unique(a,a+n)-a;即去重,返回去重后最后一个元素位置;前提是数组有序;复杂度O(n))

    JAVA在竞赛中主要应用于高精度&进制转换,因为有一个类型为BigInteger,但运行速度慢,时限为C的2-3倍
    eg.

    import java.io.*;
    import java.util.*;
    public calss Main
    {
        public static void main(String[] args)
        {
            Scanner cin=new Scanner(System.in);
            while (cin.hasNext())
            {
                int a=cin.nextInt();
                System.out.println(a);
            }
        }
    }
    
    hasNext()
    nextInt()
    next()
    nextLine()
    nextBigInteger()
    System.out.print()
    System.out.println()
    
    DecimalFormat fd=new DecimalFormat(#.00#)
    

    二分:
    eg1.给出浮点数x,求sqrt(x)

    #include<cstdio>
    #include<algorithm>
    #define eps 0.0000001
    using namespace std;
    double x,l,r,mid;
    
    int main()
    {
    	scanf("%lf",&x);
    	l=0,r=max(x,1.0);//因为若x小于1,就错误了……
    	while (r-l>eps)
    	{
    		mid=(l+r)/2;
    		if (mid*mid<=x) l=mid;
    		else r=mid; 
    	}
    	printf("%lf
    ",mid);
    	return 0;
    }
    

    eg2.查找一个有序数组中特定元素第一次出现和最后一次出现的位置
    (二分查找略)

    upper_bound(a,a+n,b)
    lower_bound(a,a+n,b)
    

    eg3.给定四个长度为n的数组,从每个数组中取一个值有多少种选择方案使四个值的和为0(n<4000)
    题解:
    因为(n^2)很小(并且主题为二分),所以考虑将前两个数组和后两个数组分别合并为一个(n^2)的数组,然后进行二分查找
    注意:需要注意在找时要看内个元素出现了几次
    另:将两个(n^2)的数组排序后可以不用二分查找,利用双指针O((n^2))实现即可(首指针升序记录第一个数组找到哪,尾指针降序记录第二个数组找到哪)

    eg4.给定一个二维数组A,相邻的两个元素保证右侧的大于左侧的,下侧的大于上侧的,查找x是否出现在此数组中(nm)
    题解:
    1、每一行或每一列(小的内个)均二分一次……复杂度O(min(n,m)
    log)
    2、从矩阵的右上角开始找,向左即为减小,向下即为增大,即出现一条分界线,界线上为小于x的元素,界线下为大于x的元素,复杂度O(n+m)

    eg4.给定一个数组A[1..n],找出一个位置使得其相邻位置的值都比当前位置小,假定A[0]=A[n+1]=-∞
    题解:
    将数组差分,因为我们可以证明两侧均为-∞时一定存在峰值,即两侧为-时中间一定有答案。所以每次选取中间的值,如果为-则在左半部分找,如果为+则在右边部分找

    eg5.设将一个数组整体右移,后侧数据移到前侧,定义为数组的旋转。给定一个可能被旋转过的单调递增数组,求该数组的最小值
    题解:
    首先判断是否被旋转过:第一个值与最后一个值比较
    每次取中间值,若小于第一个值则r=mid,否则l=mid

    二分答案(最小值最大,最大值最小):
    eg1.给出n个石头,给出到起点的距离。问去掉n个中的m个,使其间距的最小值最大
    题解:
    终极之河中跳石头,略。

    eg2.有一些衣服,每件衣服有一定水量,有一个烘干机,每次可以烘一件衣服,每分钟可以烘干k件衣服。每件衣服如果不在烘干机里每分钟可以蒸发一滴水。问最少需要多少时间烘干所有衣服。
    题解:
    高中某一次模拟的T1,略。

    eg3.给定n个物品,每个物品两个属性A与B。选取k个物品使得这些物品的A值之和除以B值之和最大。
    题解:
    01分数规划
    1、二分答案,每次对于当前mid按A-mid*B降序排序,从大向小取k个,看和是否大于等于0。//sum(A)/sum(b)>=mid
    复杂度O(nlognlogn)
    2、

    nth_element(a,a+n,k)//O(n)
    //将数组中前k大的元素放在前k个位置,但不保证顺序
    

    三分:
    要求单峰。
    注:单峰函数倒数单调,所以三分不方便时可求导后二分

    mid=(l+r)/2;
    midmid=(mid+r)/2;
    

    黄金分割三分,经实践,跑得最快

    midl=l+(r-l)*0.382;
    midr=l+(r-l)*0.618;
    

    eg1.给定一个开口向上的二次函数,设f(x)为这n个二次函数的最大值,求f(x)的极小值点
    题解:
    f(x)一定是一个单峰函数,所以三分后每次暴力取min即可

    eg2.给定一个序列A,一个区间的poorness定义为这个区间内和的绝对值,weakness等于所有区间最大的poorness。求一个x使序列A全部减x后weakness最小。(n<=2e5)
    题解:令f(x)=weakness,则f(x)为一个单峰函数(开口向上),三分求极值即可

    eg3.给定x,求((x)+(x^2)+(x^3)+...+(x^y))%p,(x,y<1e9,p>1e9)
    题解:
    1、利用等比数列求和及求逆元
    2、若x为矩阵A呢?(不能用逆元)
    利用ksm二分的思想,将其递归处理
    eg.(x+x^2+x^3+x^4)

    eg4.给定两个n位的大整数,求乘积,要求复杂度小于O(n^2)
    题解:
    折半,将两个大整数均分为前n/2位和后n/2位,变为4次(n/2)^2的乘法。
    (X=AB,Y=CD)
    (X*Y=(A*2^{n/2}+B)(C*2^{n/2})=AC*2^{n}+(AD+BC)^{n/2}+BD*2^{n})
    T(n)=4*T(n/2)+O(n);//Master定理求解复杂度问题,可知T(n)=O((n^2))
    所以还需要优化。

    wqs二分
    eg.给定n个物品,每个物品具有体积与价值,给定背包容量允许的情况下,选取不超过k个物品,可以收获的最大价值。(n<500,V<10000)
    题解:
    将每个物品的价值加x,背包容量加kx,每次做nv的背包可以知道选了多少个物品,随着x的增大,选的物品变少,最后得到答案。

    eg2.一条直线上有n个村庄,给出每个村庄的坐标(整数)。要在这条直线上选k个地方建雕像,使得每个村庄到离其最近的雕像的距离的和最小,输出最小的和。(n<100000)
    题解:
    对每个雕像增加一个代价x,二分x来建雕像以控制建雕像的个数。

  • 相关阅读:
    [编程题] 回文数问题
    [编程题] 以字符串的形式读入两个数字,再以字符串的形式输出两个数字的和
    [编程题] 合并有序链表
    [编程题] 借用栈实现链表反转
    [编程题] 二叉树求深度
    pat 甲级 1045 ( Favorite Color Stripe ) (动态规划 )
    pat 甲级 1034 ( Head of a Gang )
    PAT public bike management (30)
    PAT 甲练习 1003 Emergency
    vim 自动代码格式调整
  • 原文地址:https://www.cnblogs.com/mrha/p/12179333.html
Copyright © 2011-2022 走看看