10.1综合强化刷题 Day3 afternoon
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了10.1综合强化刷题 Day3 afternoon相关的知识,希望对你有一定的参考价值。
竞赛时间:????年??月??日??:??-??:??
题目名称 |
a |
b |
c |
名称 |
a |
b |
c |
输入 |
a.in |
b.in |
c.in |
输出 |
a.out |
b.out |
c.out |
每个测试点时限 |
1s |
1s |
1s |
内存限制 |
256MB |
256MB |
256MB |
测试点数目 |
6 |
100 或 200 |
10 |
每个测试点分值 |
16 或者 17 |
1 或 0.5 |
10 |
是否有部分分 |
无 |
无 |
无 |
题目类型 |
传统 |
传统 |
传统 |
a
【问题描述】
你是能看到第一题的 friends 呢。
——hja
给你一个只有小括号和中括号和大括号的括号序列,问该序列是否合法。
【输入格式】
一行一个括号序列。
【输出格式】
如果合法,输出 OK,否则输出 Wrong。
【样例输入】
[(])
【样例输出
Wrong
【数据范围与规定】
对于70%的数据,1 ≤ N≤ 100。
对于100%的数据,1 ≤ N≤ 10000,所有单词由大写字母组成。
简单粗暴的栈模拟
#include<cstdio> #include<cstdlib> #include<cstring> #include<iostream> #include<algorithm> #define N 10010 using namespace std; char ch[N]; int main() { freopen("a.in","r",stdin); freopen("a.out","w",stdout); cin>>ch; int l=strlen(ch); int top=0;bool flag=false; if(l%2!=0) printf("Wrong"); else { for(int i=0;i<l;i++) { if(ch[i]==‘(‘||ch[i]==‘[‘) top++; else { if(ch[i]==‘]‘) { if(!top||ch[i-1]==‘(‘) {flag=true; break;} if(ch[i-1]==‘[‘) top--; } else { if(!top||ch[i-1]==‘[‘) {flag=true; break;} if(ch[i-1]==‘(‘) top--; } } } if(!flag) printf("OK"); else printf("Wrong"); } return 0; }
b
【问题描述】
你是能看到第二题的 friends 呢。
——laekov
Yjq 想要将一个长为l 宽为 w的矩形棺材(棺材表面绝对光滑,所以棺材可以任意的滑动)拖过一个 L 型墓道。
如图所示,L 型墓道两个走廊的宽度分别是a 和 b,呈 90°,并且走廊的长度远大于l 。
现在 Hja 想知道对于给定的 a,b l, ,最大的 w是多少,如果无论如何棺材都不可能通过,则输出"My poor head =("
【输入格式】
第一行三个用空格分隔的整数a , b, l,意义如题目所示。
【输出格式】
输出最大的可能的 w,保留七位小数,如果无论如何棺材都不可能通过,则输出"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 ≤ 104。
哈哈,只输出没有解的情况能得38.5、、、
#include<cstdio> #include<cstdlib> #include<cstring> #include<iostream> #include<algorithm> using namespace std; int a,b,l; int read() { int x=0,f=1; char ch=getchar(); while(ch<‘0‘||ch>‘9‘){if(ch==‘-‘)f=-1;ch=getchar();} while(ch>=‘0‘&&ch<=‘9‘) x=x*10+ch-‘0‘,ch=getchar(); return x*f; } int main() { freopen("b.in","r",stdin); freopen("b.out","w",stdout); a=read(),b=read(),l=read(); printf("My poor head =("); 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)
//特判三种情况,一种是怎么找都能拖过去的(w最大等于l),一种是可以横着过去的(w要比b小才能过去),一种是可以竖着过去的(w要比a小才能过去)
//进行三分找最优解
//对于这个棺材我们可以知道解析式为n*x+m*y-n*m=0,(b,a)这个点到直线的距离为|n*b+m*a-n*m|/l
//我们知道我们要使棺材能过去,必须要是他在任何地方都能过去,也就是说这个棺材的w要比这个点到直线的距离的最小值小或者等于
//这样的话,我们就转换成单峰函数求最值,采用三分法
//三分法?三分法的思路与二分法很类似,不过其用途没有那么广泛,主要用于求单峰函数的极值。
while(t<100)//对于实数类型的三分或二分直接分100次就够了
//当最小值为负数的时候即为无论怎样都过不去的时候,直接输出My poor head =(
#include<cmath> #include<cstdio> #include<cstdlib> #include<cstring> #include<iostream> #include<algorithm> using namespace std; int a,b,l,t; int read() { int x=0,f=1; char ch=getchar(); while(ch<‘0‘||ch>‘9‘){if(ch==‘-‘)f=-1;ch=getchar();} while(ch>=‘0‘&&ch<=‘9‘) x=x*10+ch-‘0‘,ch=getchar(); return x*f; } double work(double n) { double m=sqrt(1.0*l*l-n*n); return (m*a+b*n-n*m)/l;//求出点到直线的距离 } int main() { freopen("b.in","r",stdin); freopen("b.out","w",stdout); a=read(),b=read(),l=read(); 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;} //特判三种情况,一种是怎么找都能拖过去的(w最大等于l),一种是可以横着过去的(w要比b小才能过去),一种是可以竖着过去的(w要比a小才能过去) double L=0,R=l,ans=-1e8,mid1,mid2,t1,t2; //进行三分找最优解 //对于这个棺材我们可以知道解析式为n*x+m*y-n*m=0,(b,a)这个点到直线的距离为|n*b+m*a-n*m|/l //我们知道我们要使棺材能过去,必须要是他在任何地方都能过去,也就是说这个棺材的w要比这个点到直线的距离的最小值小或者等于 //这样的话,我们就转换成单峰函数求最值,采用三分法 //三分法?三分法的思路与二分法很类似,不过其用途没有那么广泛,主要用于求单峰函数的极值。 while(t<100)//对于实数类型的三分或二分直接分100次就够了 { t++; mid1=(R-L)/3+L,mid2=R+L-mid1;//三分 t1=work(mid1),t2=work(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); return 0; }
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。
明明写了个60分的部分分,结果node结构体里面的数不知道怎么改,弄出负数来了,然后就只得了30分
#include<cstdio> #include<cstdlib> #include<cstring> #include<iostream> #include<algorithm> #define N 1010 using namespace std; int n,x,y,s,in[N],sum,ans,q[N][N]; int read() { int x=0,f=1; char ch=getchar(); while(ch<‘0‘||ch>‘9‘){if(ch==‘-‘)f=-1;ch=getchar();} while(ch>=‘0‘&&ch<=‘9‘) x=x*10+ch-‘0‘,ch=getchar(); return x*f; } struct Node { int num,w,s; }node[N][N]; int cmp(Node a,Node b){return a.w>b.w;} int main() { // freopen("c.in","r",stdin); // freopen("c.out","w",stdout); n=read(); for(int i=1;i<n;i++) { x=read(),y=read(); in[x]++,in[y]++; q[x][in[x]]=y; q[y][in[y]]=x; } for(int i=1;i<=n;i++) for(int j=1;j<=in[i];j++) node[i][j].num=q[i][j],node[i][j].w=in[q[i][j]],node[i][q[i][j]].s=j; for(int i=1;i<=n;i++) if(in[i]>2) { for(int j=1;j<=in[i];j++) { y=node[i][j].num; node[y][node[y][i].s].w=2; // node[y][node[y][i].s].num; } sort(node[i]+1,node[i]+1+in[i],cmp); sum=in[i]-2,in[i]=2,s=1; while(sum) { y=node[i][s].num,in[y]--; for(int j=1;j<=in[y]+1;j++) { x=node[y][j].num; node[x][node[x][y].s].w--; } ans+=2,sum--,s++; } } for(int i=1;i<=n;i++) printf("%d ",in[i]); ans+=2*n;sum=0; for(int i=1;i<=n;i++) sum+=in[i]; ans-=sum;ans/=2; printf("\\n%d",ans); return 0; }
正解树形dp,刘大佬用乱搞A掉的,由于本蒟蒻不会dp,所以听的乱搞的思路
我们先把原来的树变成一条链,然后变成链的代价+1以后就是总代价。怎样求变成链的代价呢?我们搜索整棵树,我们随便找一个入度为1的节点为根节点,然后搜索整棵树,当一个节点的度数>2的时候,我们就要对其进行删边,删去除那两条边以外的边由于我们要变成一条链,因此我们在删完边以后还要在建相同数量的边(原树的边的条数为n-1,链的条数也为n-1)因此我们这个地方要乘2,我们把这条边删去,那么他的父亲节点的入读就-1
#include<cstdio> #include<cstring> #include<cstdlib> #include<iostream> #include<algorithm> #define N 100010 using namespace std; int n,x,y,root,tot,ans,in[N],head[N<<2]; int read() { int x=0,f=1; char ch=getchar(); while(ch<‘0‘||ch>‘9‘){if(ch==‘-‘)f=-1;ch=getchar();} while(ch>=‘0‘&&ch<=‘9‘) x=x*10+ch-‘0‘,ch=getchar(); return x*f; } struct Edge { int to,next,from; }edge[N<<2]; int add(int x,int y) { tot++; edge[tot].to=y; edge[tot].next=head[x]; head[x]=tot; } void dfs(int x,int fa) { for(int i=head[x];i;i=edge[i].next) { int t=edge[i].to; if(t==fa) continue; dfs(t,x); if(in[t]>2) { in[x]--; ans+=(in[t]-2)*2; } } } int main() { freopen("c.in","r",stdin); freopen("c.out","w",stdout); n=read(); for(int i=1;i<n;i++) { x=read(),y=read(); add(x,y),add(y,x); in[x]++,in[y]++; } for(int i=1;i<=n;i++) if(in[i]==1) {root=i; break;} dfs(root,-1); printf("%d",ans+1); return 0; }
距 NOIp2017 还剩 28 天
你可以做的事情还有很多,即使到最后一秒也不要放弃,因为不到结束的那一刻谁也不知道结果会怎样。
以上是关于10.1综合强化刷题 Day3 afternoon的主要内容,如果未能解决你的问题,请参考以下文章