1. 程式人生 > >國慶 day 3 下午

國慶 day 3 下午

main 第一題 一個 想要 efi end mat har a*

a
【問題描述】
      你是能看到第一題的 friends 呢。
                      ——hja
    給你一個只有小括號和中括號和大括號的括號序列,問該序列是否合法。
【輸入格式】
  一行一個括號序列。
【輸出格式】
  如果合法,輸出 OK,否則輸出 Wrong。
【樣例輸入】
  [(])
【樣例輸出】
  Wrong
【數據範圍與規定】
  對於70%的數據,1 ≤n≤ 100。
  對於100%的數據,1 ≤ n≤ 10000,所有單詞由大寫字母組成。
P100 zhxb
思路:棧維護一下。

技術分享
#include<cstdio>
#include
<cstring> #include<iostream> using namespace std; string s; char stack[10100]; int top,m1,m2,m3; int main(){ freopen("a.in","r",stdin); freopen("a.out","w",stdout); cin>>s; int len=s.length(); for(int i=0;i<len;i++){ if(s[i]==() {m1++;stack[top++]=s[i];}
if(s[i]==[) {m2++;stack[top++]=s[i];} if(s[i]=={) {m3++;stack[top++]=s[i];} else if(s[i]==)){ if(!m1){cout<<"Wrong";return 0;} else if(stack[top-1]!=(){cout<<"Wrong";return 0;} else{top--;m1--;} } else if(s[i]==
]){ if(!m2){cout<<"Wrong";return 0;} else if(stack[top-1]!=[){cout<<"Wrong";return 0;} else {top--;m2--;} } else if(s[i]==}){ if(!m3){cout<<"Wrong";return 0;} else if(stack[top-1]!={){cout<<"Wrong";return 0;} else {top--;m3--;} } } if(top||m1||m2||m3) cout<<"Wrong"; else cout<<"OK"; }
View Code

b
【問題描述】
      你是能看到第二題的 friends 呢。
                      ——laekov
    Yjq 想要將一個長為l寬為w的矩形棺材(棺材表面絕對光滑,所以棺材可
  以任意的滑動)拖過一個 L 型墓道。
    如圖所示,L 型墓道兩個走廊的寬度分別是a和b,呈 90°,並且走廊的長
  度遠大於?。
    現在 Hja 想知道對於給定的a,b,l,最大的?是多少,如果無論如何棺材都
  不可能通過,則輸出"My poor head =("
【輸入格式】
  第一行三個用空格分隔的整數a,b,l,意義如題目所示。
【輸出格式】
  輸出最大的可能的?,保留七位小數,如果無論如何棺材都不可能通過,則
  輸出"My poor head =("。
【樣例輸入 1】
  2 2 1
【樣例輸出 1】
  1.0000000

【樣例輸入 2】
  2 2 2
【樣例輸出 2】
  2.0000000
【樣例輸入 3】
  2 2 3
【樣例輸出 3】
  1.3284271
【樣例輸入 4】
  2 2 6
【樣例輸出 4】
  My poor head =(
【數據範圍與規定】
  對於100%的數據,1 ≤ a,b,l ≤ 10 4
  P100 zhxc

以下解題思路來自xxy大佬的博客

技術分享

設直線解析式為 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 * n - a * m + n * m 的最大值

然後不知道為啥求了個

b * n + a * m - n *m 的最小值

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

式子最小值<0 時無解

技術分享
#include<cmath>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
const double eps=1e-9;
int a,b,l;
double L=0,R=1;
double ans=0x7f7f7f7f;
double mid1,mid2,t1,t2;
double f(double n){
    double m=sqrt(1.0*l*l-n-n);
    if(n*m>a*n+b*m)    return -1;
    return (b*m+a*n-n*m)/l;
}
int main(){
    freopen("b.in","r",stdin);
    freopen("b.out","w",stdout);
    scanf("%d%d%d",&a,&b,&l);
    if(a>=1&&b>=1){
        printf("%d.0000000",l);
        return 0;
    }
    if(a>=l){
        printf("%d.0000000",b);
        return 0;
    }
    if(b>=1){
        printf("%d.0000000",a);
        return 0;
    }
    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=min(ans,t1);
            R=mid2;
        }
        else{
            ans=min(ans,t2);
            L=mid1;
        }
    }
    printf("%.7lf",ans);
}
View Code


c
【問題描述】
      你是能看到第三題的 friends 呢。
                      ——aoao
    樹是個好東西,刪掉樹一條邊要 1 的代價,隨便再加一條邊有 1 的代價,求
  最小的代價把樹變成環。
【輸入格式】
  第一行一個整數n,代表樹的點數。
  接下來n − 1行,每行兩個數代表樹的一條邊。
【輸出格式】
  一行一個整數代表答案。
【樣例輸入】
  4
  1 2
  2 3
  2 4
【樣例輸出】
  3
【數據規模與約定】
  對於30%的數據,1≤n≤10。
  對於60%的數據,1 ≤ n ≤ 1000。
  對於100%的數據,1 ≤ n ≤ 100000。

思路:貪心。

技術分享
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#define MAXN 100010
using namespace std;
int n,tot,ans,root;
int into[MAXN];
int to[MAXN*2],net[MAXN*2],head[MAXN*2];
void add(int u,int v){
    to[++tot]=v;net[tot]=head[u];head[u]=tot;
    to[++tot]=u;net[tot]=head[v];head[v]=tot;
}
void dfs(int now,int fa){
    for(int i=head[now];i;i=net[i])
        if(to[i]!=fa){
            dfs(to[i],now);
            if(into[to[i]]>2){
                into[now]--;
                ans+=(into[to[i]]-2)*2;
            }
        }
}
int main(){
    freopen("c.in","r",stdin);
    freopen("c.out","w",stdout);
    scanf("%d",&n);
    for(int i=1;i<n;i++){
        int u,v;
        scanf("%d%d",&u,&v);
        add(u,v);
        into[u]++;
        into[v]++;
    }
    root=1;
    for(int i=1;i<=n;i++)
        if(into[i]==1){
            root=i;
            break;
        }
    dfs(root,-1);
    cout<<ans+1;
}
/*
8
1 2
1 3
3 4
3 5
4 6
4 7
4 8
3
*/
View Code

國慶 day 3 下午