突然发现上一场没有写,那就补补吧
本来这场应该5题的,结果一念之差E fail了
A. Serval and Bus
基本数学不解释,假如你没有+1 -1真的不好意思见人了
#include#include #include #include #include #include using namespace std;const int _=1e2;int s[110],d[110];int main(){ int n,T,mn=0; scanf("%d%d",&n,&T); for(int i=1;i<=n;i++) { scanf("%d%d",&s[i],&d[i]); if(s[i]
B. Serval and Toy Bricks
直接行列取min完事
#include#include #include #include #include #include using namespace std;const int _=1e2;int a[110],b[110],c[110][110];int main(){ int n,m,h; scanf("%d%d%d",&n,&m,&h); for(int i=1;i<=m;i++)scanf("%d",&a[i]); for(int i=1;i<=n;i++)scanf("%d",&b[i]); for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) scanf("%d",&c[i][j]); for(int i=1;i<=n;i++) { for(int j=1;j<=m;j++) { if(c[i][j]==0)printf("0"); else { printf("%d",min(b[i],a[j])); } putchar(j==m?'\n':' '); } } return 0;}
C. Serval and Parenthesis Sequence
这题明显乱搞了,场上看错题意又写了个假的做法,最后迷迷糊糊乱搞了出来。
就是(不足n/2就先放就没了,这种东西都fail了两发
#include#include #include #include #include #include using namespace std;char ss[310000]; int num[310000];int main(){ int n; scanf("%d%s",&n,ss+1); if(n%2==1){puts(":(");return 0;} for(int i=n;i>=1;i--)num[i]=num[i+1]+(ss[i]=='('?1:0); int le=0,s=0; for(int i=1;i<=n;i++) { if(ss[i]=='(')le++,s++; else if(ss[i]==')') { if(le>0) { le--; if(le==0&&i!=n){puts(":(");return 0;} } else {puts(":(");return 0;} } else { if(s+num[i+1] n/2){puts(":(");return 0;} for(int i=1;i<=n;i++)printf("%c",ss[i]); return 0;}
D. Serval and Rooted Tree
这个题明显就是见过的套路,max就是子树max+其他子树的tot,min就是每个子树都取到max-1再+1
先是以为min是取max(子树max)wa了,然后又没用maxn搞的数组少一个0,这个时候心态已经崩了,zory 50min之前就做完了A~D
#include#include #include #include #include #include using namespace std;struct node{ int x,y,next;}a[310000];int len,last[310000];void ins(int x,int y){ len++; a[len].x=x;a[len].y=y; a[len].next=last[x];last[x]=len;}int op[310000],le[310000],mx[310000];void dfs(int x){ if(last[x]==0)le[x]=1,mx[x]=1; else { if(op[x]==1) { int p1=0; for(int k=last[x];k;k=a[k].next) { int y=a[k].y; dfs(y); le[x]+=le[y]; if(p1==0||mx[y]-le[y]>mx[p1]-le[p1])p1=y; } mx[x]=le[x]-le[p1]+mx[p1]; } else { int num=0; for(int k=last[x];k;k=a[k].next) { int y=a[k].y; dfs(y); le[x]+=le[y]; num+=mx[y]-1; } mx[x]=num+1; } }}int main(){ int n; scanf("%d",&n); for(int i=1;i<=n;i++)scanf("%d",&op[i]); int F; for(int i=2;i<=n;i++) { scanf("%d",&F); ins(F,i); } dfs(1); printf("%d\n",mx[1]); return 0;}
E. Serval and Snake
结果突然不困了,发现这个E是个SB题,假如这个矩形里面有头或尾之一,那么他的度数就是1,直接枚举行列就可以定位,对于两个点在同一行/列的二分答案就好了,结果写萎了要算2020次正好被卡飞,第二天就被rose_king D飞了
#include#include #include #include #include #include using namespace std;bool check1(int t,int x,int y){ printf("? %d %d %d %d\n",t,x,t,y); fflush(stdout); int k;scanf("%d",&k); return k%2==1;}bool check2(int t,int x,int y){ printf("? %d %d %d %d\n",x,t,y,t); fflush(stdout); int k;scanf("%d",&k); return k%2==1;}int main(){ int n; scanf("%d",&n); int ax,ay,bx,by,k,op=0; for(int i=1;i<=n;i++) { if(i==n&&op==0)break; printf("? 1 1 %d %d\n",i,n); fflush(stdout); scanf("%d",&k); if(k%2==1&&op==0) { ax=i; int l=1,r=n; while(l<=r) { int mid=(l+r)/2; if(check1(i,l,mid))r=mid; else l=mid+1; if(l==r){ay=l;break;} } op=1; } if(k%2==0&&op==1) { bx=i; int l=1,r=n; while(l<=r) { int mid=(l+r)/2; if(check1(i,l,mid))r=mid; else l=mid+1; if(l==r){by=l;break;} } printf("! %d %d %d %d\n",ax,ay,bx,by); fflush(stdout); return 0; } } op=0; for(int j=1;j<=n;j++) { printf("? 1 1 %d %d\n",n,j); fflush(stdout); scanf("%d",&k); if(k%2==1&&op==0) { ay=j; int l=1,r=n; while(l<=r) { int mid=(l+r)/2; if(check2(j,l,mid))r=mid; else l=mid+1; if(l==r){ax=l;break;} } op=1; } if(k%2==0&&op==1) { by=j; int l=1,r=n; while(l<=r) { int mid=(l+r)/2; if(check2(j,l,mid))r=mid; else l=mid+1; if(l==r){bx=l;break;} } printf("! %d %d %d %d\n",ax,ay,bx,by); fflush(stdout); return 0; } } return 0;}
结果zory A fail了都比我高。。