• 2017北京国庆刷题Day3 afternoon


    期望得分:100+0+30=130

    实际得分:100+36.5+0=136.5

    T3 一个变量写混了,丢了30。。

    模拟栈

    #include<cstdio>
    #include<cstring>
    using namespace std;
    #define N 10001
    char s[N];
    int st[N],top;
    int main()
    {
        freopen("a.in","r",stdin);
        freopen("a.out","w",stdout);
        scanf("%s",s);
        int len=strlen(s);
        for(int i=0;i<len;i++)
            if(s[i]=='(') st[++top]=1;
            else if(s[i]=='[') st[++top]=2;
            else if(s[i]=='{') st[++top]=3;
            else if(s[i]==')') 
            {
                if(st[top]==1) top--;
                else { printf("Wrong");return 0; }
            }
            else if(s[i]==']')
            {
                if(st[top]==2) top--;
                else { printf("Wrong"); return 0; }
            }
            else
            {
                if(st[top]==3) top--;
                else { printf("Wrong"); return 0; }
            }
        if(top) printf("Wrong");
        else printf("OK");
        return 0;
    }
    View Code

     

    设直线解析式为 y=(-n/m)* x+n

    整理,得:n * x + m * y - n * m = 0

    点(b,a)到直线的距离为:|  b * n + a * m - n * m | / L

    (L : 根号下(n^2 + m^2)=L)

    棺材能够在这里拐弯

    直观上感受就是棺材拐弯的全程不被点(b,a)卡住

    所以 最优解 是  b * n + a * m - n * m / L 的最小值

    为什么这里把绝对值去掉?

    因为 当式子<0 时,直线到了点的右上方,就是不合法解,此时棺材不能通过

    单峰函数求最小值,三分法每次去掉大的一部分

    注意特判直接横着/竖着就能拖过去的情况

    #include<algorithm>
    #include<cstdio>
    #include<cmath>
    
    using namespace std;
    const double eps=1e-9;
    
    int a,b,l;
    
    double f(double n)
    {
        double m=sqrt(1.0*l*l-n*n);
        return (b*n+a*m-n*m)/l;
    }
    
    int main()
    {
        freopen("b.in","r",stdin);
        freopen("b.out","w",stdout);
        scanf("%d%d%d",&a,&b,&l);
        if(a>=l && b>=l) { printf("%d.0000000",l); return 0; }
        if(a>=l) { printf("%d.0000000",b); return 0; }
        if(b>=l) { printf("%d.0000000",a); return 0; }
        double L=0,R=l,ans=-1e18,mid1,mid2,t1,t2;
        int T=100;
        while(T--)
        {
            mid1=(R-L)/3+L; mid2=L+R-mid1;
            t1=f(mid1); t2=f(mid2);
            if(t1<0 || t2<0) { printf("My poor head =("); return 0; }
            if(t1<t2) ans=t1,R=mid2;
            else ans=t2,L=mid1;
        }
        printf("%.7lf",ans);
    }
    View Code

    递归回溯时贪心

    如果当前点的分支个数>=2,那么断掉它与父节点的边,子节点中只留两个最优

    所以 ans+=分支个数-2+1

    加1是因为还要断掉与父节点的连边

    但是如果是递归的根节点,就是ans+=分支个数-2

    如果当前只有一个分支,那就不用断,仍然是它的父节点的一个分支

    最终的答案就是ans*2+1

    *2是因为断掉一个,相应的就要添加一条

    +1是最后要形成一个环

    #include<cstdio>
    #include<iostream>
    
    #define N 100001
    
    using namespace std;
    
    int front[N],nxt[N<<1],to[N<<1],tot;
    int ans;
    
    void read(int &x)
    {
        x=0; char c=getchar();
        while(!isdigit(c)) c=getchar();
        while(isdigit(c)) { x=x*10+c-'0'; c=getchar(); }
    }
    
    void add(int u,int v)
    {
        to[++tot]=v; nxt[tot]=front[u]; front[u]=tot;
        to[++tot]=u; nxt[tot]=front[v]; front[v]=tot;
    }
    
    int dfs(int x,int f)
    {
        int sum=0;
        for(int i=front[x];i;i=nxt[i])
            if(to[i]!=f) sum+=dfs(to[i],x);
        if(sum>=2)
        {
            if(x==1) ans+=sum-2;
            else ans+=sum-1;
            return 0;
        }
        return 1;
    }
    
    int main()
    {
        freopen("c.in","r",stdin);
        freopen("c.out","w",stdout);
        int n,u,v;
        read(n);
        for(int i=1;i<n;i++) read(u),read(v),add(u,v);
        dfs(1,0);
        printf("%d",ans*2+1);
    }
    View Code
  • 相关阅读:
    LeetCode 42. Trapping Rain Water
    LeetCode 209. Minimum Size Subarray Sum
    LeetCode 50. Pow(x, n)
    LeetCode 80. Remove Duplicates from Sorted Array II
    Window10 激活
    Premiere 关键帧缩放
    AE 「酷酷的藤」特效字幕制作方法
    51Talk第一天 培训系列1
    Premiere 视频转场
    Premiere 暴徒生活Thug Life
  • 原文地址:https://www.cnblogs.com/TheRoadToTheGold/p/7642212.html
Copyright © 2020-2023  润新知