2017北京国庆刷题Day3 afternoon

 

 2017北京国庆刷题Day3 afternoon

 

 

 

#include<iostream>
#include<cstdio>
#include<cstring>

#define N 10007

using namespace std;
int n,m,cnt,top;
char s[N],sta[N];

int main()
{
    freopen("a.in","r",stdin);
    freopen("a.out","w",stdout);
    scanf("%s",s);n=strlen(s);
    if(!n) {printf("OK\n");return 0;}
    for(int i=0;i<n;i++)
    {
        if(i==0 && (s[i]==')' || s[i]==']' || s[i]=='}')) 
        {
            printf("Wrong\n");
            return 0;
        }
        if(s[i]=='(' || s[i]=='[' || s[i]=='{') sta[top++]=s[i];
        else
        {
            if((s[i]==']' && sta[top-1]=='[') || (s[i]==')' 
            && sta[top-1]=='(') || (s[i]=='}' && sta[top-1]=='{')) top--;
            else 
            {
                printf("Wrong\n");
                return 0;
            }
        }
    }
    if(top==0) printf("OK\n");
    else printf("Wrong\n");
    fclose(stdin);fclose(stdout);
    return 0;  
}

 

 


 

 

/*
设直线解析式为 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)
zui优解 是  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);
}

 

 


 

/*
贪心
如果当前点的分支个数>=2,那么断掉它与父节点的边,子节点中只留两个最优
所以 ans+=分支个数-2
但是如果是递归的根节点,就是ans+=分支个数-1
因为根节点可以与两个分支相连
如果当前只有一个分支,那就不用断,仍然是它的父节点的一个分支
最终的答案就是ans*2+1
*2是因为断掉一个,相应的就要添加一条
+1是最后要形成一个环
*/
#include<iostream>
#include<cstdio>
#include<cstring>

#define N 100007

using namespace std;
int n,m,k,ans,cnt;
int head[N];
struct edge{
    int u,v,net;
}e[N<<1];

inline int read()
{
    int x=0,f=1;char c=getchar();
    while(c>'9'||c<'0'){if(c=='-')f=-1;c=getchar();}
    while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();}
    return x*f;
}

inline void add(int u,int v)
{
    e[++cnt].v=v;e[cnt].net=head[u];head[u]=cnt;
}

int dfs(int u,int fa)
{
    int sum=0;
    for(int i=head[u];i;i=e[i].net) if(e[i].v!=fa) sum+=dfs(e[i].v,u);
    if(sum>1)
    {
        if(u==1) ans+=sum-2;
        else ans+=sum-1;
        return 0;
        
    }return 1;
}

int main()
{
    n=read();int x,y;
    for(int i=1;i<n;i++)
    {
        x=read();y=read();
        add(x,y);add(y,x);
    }
    dfs(1,0);
    printf("%d\n",ans*2+1);
    return 0;
}

 

posted @ 2017-10-15 14:55  安月冷  阅读(196)  评论(0编辑  收藏  举报