zoukankan      html  css  js  c++  java
  • 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
  • 相关阅读:
    UVA10340
    声明顺序 (Bootstrap 编码规范)
    使用SVN小结
    通过LINQ TO SQL类显示数据库表的数据
    大学初进团队感想
    51NOD:1639-绑鞋带
    Codeforces Round #464 (Div. 2) E. Maximize!
    Codeforces Round #464 (Div. 2) D. Love Rescue
    Codeforces Round #464 (Div. 2) C. Convenient For Everybody
    Codeforces Round #464 (Div. 2) B. Hamster Farm
  • 原文地址:https://www.cnblogs.com/TheRoadToTheGold/p/7642212.html
Copyright © 2011-2022 走看看