【Codeforces】Codeforces Round #551 (Div. 2) 解题报告
Posted on 2019-04-15 20:58 opethrax 阅读(197) 评论(0) 编辑 收藏 举报这一个月有点松弛了,吃了好多亏。这一个月来打的第一场CF就当成是停止放松的开始吧。
在写A的时候用到了一个叫做fst的变量,于是...但是还是涨了一点点分(我上次是多惨啊)。
不敢tui不敢tui...自闭+自卑了。
A. Serval and Bus
题目大意:一个傻憨憨t时到车站,见车就坐,给出每辆公交车首班车到达时间及之后的时间间隔,求傻憨憨最后上的是哪一辆车。
数据范围:1 ≤ 𝑛 ≤ 100 , 1 ≤ n ≤ 100 , 1 ≤ t ≤ 105 , 1 ≤ si,di ≤ 105
无代码
数据范围:1≤𝑛,𝑚,ℎ≤100
无代码
题目大意:有一个括号序列,要求它本身合法且它的所有前缀都严格不合法,现在有一些位置不确定,求一种合法方案,否则输出 " :( " (我跟你讲我现在就这个表情)
数据范围:1 ≤ |s| ≤ 105
先判无解,再贪心,尽可能先放做括号 "(" 这样前缀就不容易出现合法的,最后再判下合法就可以了。
无代码
对于min节点来说,如果有x个儿子,那么就只能取到第x小的元素,取不到前dp[i]个。令dp[i]表示i的儿子中取不到前dp[i]个,min节点取它儿子dp的和,max节点取它儿子dp的最小值,答案为k-dp[1]+1
代码:
1 #include<stdio.h> 2 #include<string.h> 3 #include<algorithm> 4 #include<vector> 5 using namespace std; 6 7 template<class T>void read(T &x){ 8 x=0; bool f=0; char c=getchar(); 9 while(c<'0'||'9'<c){f|=(c=='-'); c=getchar();} 10 while('0'<=c&&c<='9'){x=(x<<1)+(x<<3)+(c^48); c=getchar();} 11 x=f?-x:x; 12 } 13 14 const int N=300050; 15 const int inf=N; 16 int n,k; 17 int a[N],fa[N],dp[N]; 18 vector<int>son[N]; 19 20 void dfs(int x){ 21 if(son[x].size()==0){dp[x]=1; ++k; return ;} 22 a[x]?dp[x]=inf:dp[x]=0; 23 for(int i=son[x].size()-1,y;~i;--i){ 24 y=son[x][i]; 25 dfs(y); 26 a[x]?dp[x]=min(dp[x],dp[y]):dp[x]+=dp[y]; 27 } 28 } 29 int main(){ 30 read(n); 31 for(int i=1;i<=n;++i)read(a[i]); 32 for(int i=2;i<=n;++i)read(fa[i]), son[fa[i]].push_back(i); 33 dfs(1); 34 printf("%d",k-dp[1]+1); 35 return 0; 36 }
数据范围:(交互! 贯彻了交互题都是水题但是像我这样的傻憨憨不看的精神???)在一个n×n的网格里有一条蛇,我们向交互库查询它的一个子网格,并且告诉你蛇的身体经过这个子网格边界的次数(交点)。请在2019次查询内找到蛇头和蛇尾的位置(不需要区分头尾)。
数据范围:2≤𝑛≤1000
仔细想想我们发现在一个网格图中如果不包含蛇的头或尾是蛇的身体的一部分,就是一进一出,一进一出,一进一出...交点个数是偶数。反之就必然有头或尾在网格中。
我们先询问所有行和列(2*n次询问至多2000次),一定得到至少两行或者两列是奇数:头和尾在这两行或列中。
如果只有两行或者两列是奇数,那么蛇头蛇尾在同一行或者列中,用剩下的次数二分这行(列)的位置。
否则就是在不同的行列中,查询一次就可以确定两个点的位置。
代码:
1 #include<stdio.h> 2 #include<string.h> 3 #include<algorithm> 4 using namespace std; 5 6 inline int read(){ 7 int x=0; char c=getchar(); 8 while(c<'0'||'9'<c)c=getchar(); 9 while('0'<=c&&c<='9'){x=(x<<3)+(x<<1)+(c^48); c=getchar();} 10 return x; 11 } 12 13 int n; 14 int h[3],p[3]; 15 int a,b; 16 17 int ask(int a,int b,int c,int d){ 18 fflush(stdout); 19 printf("? %d %d %d %d\n",a,b,c,d); 20 fflush(stdout); 21 return read()&1; 22 } 23 24 int main(){ 25 n=read(); 26 for(int i=1;i<=n;++i){ 27 if(ask(i,1,i,n))h[++a]=i; 28 if(a>=2)break; 29 } 30 for(int i=1;i<=n;++i){ 31 if(ask(1,i,n,i))p[++b]=i; 32 if(b>=2)break; 33 } 34 if(a&&b){ 35 if(ask(h[1],p[1],h[1],p[1]))printf("! %d %d %d %d\n",h[1],p[1],h[2],p[2]); 36 else printf("! %d %d %d %d\n",h[1],p[2],h[2],p[1]); 37 return 0; 38 } 39 if(!a){ 40 int l=1,r=n,mid,ans; 41 while(l<=r){ 42 mid=(l+r)>>1; 43 if(ask(1,p[1],mid,p[1])){ 44 ans=mid; 45 r=mid-1; 46 } 47 else l=mid+1; 48 } 49 printf("! %d %d %d %d\n",ans,p[1],ans,p[2]); 50 return 0; 51 } 52 if(!b){ 53 int l=1,r=n,mid,ans; 54 while(l<=r){ 55 mid=(l+r)>>1; 56 if(ask(h[1],1,h[1],mid)){ 57 ans=mid; 58 r=mid-1; 59 } 60 else l=mid+1; 61 } 62 printf("! %d %d %d %d\n",h[1],ans,h[2],ans); 63 return 0; 64 } 65 }
数据范围: