SDWC补题计划--基础班DAY1
Posted shzr
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了SDWC补题计划--基础班DAY1相关的知识,希望对你有一定的参考价值。
2018的寒假去了SD的冬令营,因为一班二班难度悬殊,对我很不友好,几乎什么也没学会,但是我把两个班的课件都存了下来,现在慢慢把两个班的例题以及课后题都补一补(毕竟冬令营的钱不能白花)。
这些题目横跨各大知名题库以及一大批外国题库,以至于我注册了一批新账号......
基础班DAY1:
这一天的课事实上我并没有去听,而是去二班考试并愉快的爆零了,幸好不大难,自己看也能学会。
DAY1主要讲了队列,栈,堆,(加权)并查集。还提出了“因为数组也是数据结构,所以一切题目都是数据结构题”的精彩言论。
UVA514 Rails:https://www.luogu.org/problemnew/show/UVA514
题目概述:(火车,铁轨,车厢……)有一个无限大的栈,按照1-n的顺序依次入栈,询问是否能生成给定的出栈序。
栈的题目,模拟。以前练习初赛时见过这种题的手画版本...事实上也就是那个思路。如果现在想让一个数出栈,可是它还没入栈,就不停的入栈直到它入栈后再弹出;如果它已经在栈里,则必须是栈顶,否则就无法生成这个序列。这题在洛谷上难度虚高,主要是读入很奇妙;输出时如果n将要变化了,要换行,样例里却没换,导致很容易wa。
# include <cstdio> # include <iostream> # include <cstring> using namespace std; int n; int a[1005],sta[1005],h=0,q=0,s=0; int main() { scanf("%d",&n); while (n) { memset(a,1,sizeof(a)); scanf("%d",&a[1]); while (a[1]!=0) { for (int i=2;i<=n;i++) scanf("%d",&a[i]); q=s=1; h=0; for (int i=1;i<=n;++i) { while(s<=a[i]) sta[++h]=s++; while(sta[h]==a[q]) q++,h--; } if(s!=n+1||h!=0||q!=n+1) printf("No "); else printf("Yes "); scanf("%d",&a[1]); } printf(" "); scanf("%d",&n); } return 0; }
NOI2001 食物链:https://www.luogu.org/problemnew/show/P2024
题目概述:有三种动物,食物关系竟然形成了一个环(好不科学啊),给出一些描述:A被B吃,A吃B,A与B是同类,默认先说的话是正确的,并以此判断一共有几句假话。
大概是加权并查集最著名的习题了,也可以不用加权做,注意一下加权并查集的路径压缩,还是挺容易写错的。
int father(int x) { if (x!=f[x]) { int aa=father(f[x]); v[x]=(v[x]+v[f[x]])%3; f[x]=aa; } return f[x]; }
有一个地方一定要想清楚,在同一个并查集里的元素并不一定是同种生物,只是可以确定相对的关系,如果这里明白了也就比较简单了。
带权并查集的集合合并也别写错啦...就是解一个方程。
# include <cstdio> # include <iostream> using namespace std; int f[50005]={0},v[50005]={0}; int n,k,x,y,z,S=0; int father(int x) { if (x!=f[x]) { int aa=father(f[x]); v[x]=(v[x]+v[f[x]])%3; f[x]=aa; } return f[x]; } bool Ya(int x,int y,int z) { int a=father(y); int b=father(z); if (a==b) { if(x==1) { if(v[y]==v[z]) return true; return false; } if (x==2) { if(v[z]-v[y]!=-2&&v[z]-v[y]!=1) return false; return true; } } if (a!=b) { if(x==1) { v[b]=(v[y]-v[z]+3)%3; f[b]=a; } if (x==2) { v[b]=(v[y]-v[z]+4)%3; f[b]=a; } return true; } } int main() { scanf("%d%d",&n,&k); for (int i=1;i<=n;i++) { f[i]=i; v[i]=0; } for (int i=1;i<=k;i++) { scanf("%d%d%d",&x,&y,&z); if (z>n||y>n) S++; else if (y==z&&x==2) S++; else if (Ya(x,y,z)==false) S++; } printf("%d",S); return 0; }
以上是关于SDWC补题计划--基础班DAY1的主要内容,如果未能解决你的问题,请参考以下文章
洛谷P1080 [NOIP2012提高组D1T2]国王游戏 [2017年5月计划 清北学堂51精英班Day1]