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