【题解】AtCoder Beginner Contest 240
A - Edge Checker
题面
过水,点链接罢
思路
特判特判就好啦~
代码
//吾日八省吾身:
//输入多而不快读乎?
//题目标注而不freopen乎?
//乘除并列先乘后除乎?
//不手撕样例直接写代码乎?
//不仔细读题直接关页面乎?
//1e9而不开long long乎?
//Ctrl+V而不改名称乎?(papaw->papan IMPLIES tg1=->2=)
//相信评测神机乎?
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<string>
#include<cmath>
#include<iomanip>
#include<cctype>
#include<vector>
#include<stack>
#include<queue>
#include<map>
#include<set>
#include<algorithm>
#include<utility>
#include<deque>
#include<ctime>
#include<sstream>
#include<list>
#include<bitset>
using namespace std;
int a,b;
int main(){
cin>>a>>b;
if((min(a,b)+1==max(a,b))||(min(a,b)==1&&max(a,b)==10)) cout<<"Yes\n";
else cout<<"No\n";
return 0;
}
B - Count Distinct Integers
题面
给定数列,求不同元素个数
思路
map 大法好!
代码
//吾日八省吾身:
//输入多而不快读乎?
//题目标注而不freopen乎?
//乘除并列先乘后除乎?
//不手撕样例直接写代码乎?
//不仔细读题直接关页面乎?
//1e9而不开long long乎?
//Ctrl+V而不改名称乎?(papaw->papan IMPLIES tg1=->2=)
//相信评测神机乎?
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<string>
#include<cmath>
#include<iomanip>
#include<cctype>
#include<vector>
#include<stack>
#include<queue>
#include<map>
#include<set>
#include<algorithm>
#include<utility>
#include<deque>
#include<ctime>
#include<sstream>
#include<list>
#include<bitset>
using namespace std;
map<int,int> fafa;
int n;
int ans;
int main(){
cin>>n;
for(int i=1;i<=n;++i){
int a;
cin>>a;
if(!fafa[a]){
fafa[a]++;
ans++;
}
}
cout<<ans<<endl;
return 0;
}
C - Jumping Takahashi
题面
n行,每次给你两个数,每行只能选一个,问能不能凑出来x
思路
采用打标记的方法,剪剪枝再滚一滚(数据这么小甚至滚动数组都不需要呢)就好啦
复杂度 \(\Theta(nx)\)
代码
//吾日八省吾身:
//输入多而不快读乎?
//题目标注而不freopen乎?
//乘除并列先乘后除乎?
//不手撕样例直接写代码乎?
//不仔细读题直接关页面乎?
//1e9而不开long long乎?
//Ctrl+V而不改名称乎?(papaw->papan IMPLIES tg1=->2=)
//相信评测神机乎?
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<string>
#include<cmath>
#include<iomanip>
#include<cctype>
#include<vector>
#include<stack>
#include<queue>
#include<map>
#include<set>
#include<algorithm>
#include<utility>
#include<deque>
#include<ctime>
#include<sstream>
#include<list>
#include<bitset>
using namespace std;
bool cc[102333][2];
int n,a,b,x,v,bef;
int main(){
cin>>n>>x;
cc[0][0]=true;
for(int i=1;i<=n;++i){
cin>>a>>b;
v=i&1;bef=v^1;
for(int j=0;j<=x;++j){
if((j+a)>x&&(j+b)>x) break;
if(!cc[j][bef]) continue;
if(j+a<=x) cc[j+a][v]=true;
if(j+b<=x) cc[j+b][v]=true;
}
for(int j=0;j<=x;++j) cc[j][bef]=false;
}
if(cc[x][v]) printf("Yes\n");
else printf("No\n");
return 0;
}
D - Strange Balls
题面
往一个栈里扔元素,如果有k个k在一起就消消乐
思路
因为只可能从顶上消,所以不会有连锁反应,直接模拟即可
复杂度 \(\Theta(n)\)
代码
//吾日八省吾身:
//输入多而不快读乎?
//题目标注而不freopen乎?
//乘除并列先乘后除乎?
//不手撕样例直接写代码乎?
//不仔细读题直接关页面乎?
//1e9而不开long long乎?
//Ctrl+V而不改名称乎?(papaw->papan IMPLIES tg1=->2=)
//相信评测神机乎?
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<string>
#include<cmath>
#include<iomanip>
#include<cctype>
#include<vector>
#include<stack>
#include<queue>
#include<map>
#include<set>
#include<algorithm>
#include<utility>
#include<deque>
#include<ctime>
#include<sstream>
#include<list>
#include<bitset>
using namespace std;
struct pos{
int num,sum;
}nnn[114514];
int top,nbb;
int n,a;
int main(){
cin>>n;
for(int i=1;i<=n;++i){
cin>>a;
if(!top||nnn[top].num!=a) nnn[++top].num=a;
nnn[top].sum++;
nbb++;
if(nnn[top].num&&(nnn[top].sum==nnn[top].num)){
nbb-=nnn[top].sum;
nnn[top].num=nnn[top].sum=0;
top--;
}
cout<<nbb<<endl;
}
return 0;
}
E - Ranges on Tree
题面
给你一棵树,让你给每个点分配一个区间,使得有祖孙关系的节点有包含关系(祖包含孙),兄弟间不相交
思路
首先想到的是 dfn ,但是随即发现,如果父亲节点只有一个儿子,则该儿子可以 直接继承 父亲节点的答案,反过来说,只有出现多个儿子,才需要分配 多个不重合 的区间
一直到叶子们的父亲,我们发现,叶子们的父亲需要分配的 最短区间 长度刚好是 他的叶子数量之和 (因为每个叶子只需要 1 即可),继续向上,发现最短区间又变成了 儿子们的最短区间长度之和
也就是说,一个节点最少需要多长的区间取决于以它为根的子树内有多少个 叶子 ,可以直接 DFS 预处理
另外,由于需要 1 号点的区间的右端点最小(稍微想想就会发现确实等同于这个),所以显然要把每个叶子需要的区间挤在一起且左端点为 1 ,对应的右端点最小的区间也就是 \(1\sim 叶子个数\) ,至于儿子们的答案,同理,挨个分配即可,不过注意左端点要 随着分配而变化
代码
//吾日八省吾身:
//输入多而不快读乎?
//题目标注而不freopen乎?
//乘除并列先乘后除乎?
//不手撕样例直接写代码乎?
//不仔细读题直接关页面乎?
//1e9而不开long long乎?
//Ctrl+V而不改名称乎?(papaw->papan IMPLIES tg1=->2=)
//相信评测神机乎?
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<string>
#include<cmath>
#include<iomanip>
#include<cctype>
#include<vector>
#include<stack>
#include<queue>
#include<map>
#include<set>
#include<algorithm>
#include<utility>
#include<deque>
#include<ctime>
#include<sstream>
#include<list>
#include<bitset>
using namespace std;
const int MAXN(200233);
struct edge{
int nxt,to;
}ed[MAXN<<1];
int head[MAXN],cnt;
int lfs[MAXN],lll[MAXN],rrr[MAXN];
int n,a,b;
void add(int from,int to){
ed[++cnt].to=to;
ed[cnt].nxt=head[from];
head[from]=cnt;
return;
}
int DFL(int now,int fa){
// cout<<"e:"<<now<<endl;
bool hason=false;
for(int i=head[now];i;i=ed[i].nxt){
int tt=ed[i].to;
if(tt==fa) continue;
hason=true;
lfs[now]+=DFL(tt,now);
}
lfs[now]+=(!hason);
// cout<<"l:"<<now<<endl;
return lfs[now];
}
void DFS(int now,int fa,int l,int r){
lll[now]=l,rrr[now]=r;
int possss=l;
for(int i=head[now];i;i=ed[i].nxt){
int tt=ed[i].to;
int sis=lfs[tt];
if(tt==fa) continue;
DFS(tt,now,possss,possss+sis-1);
possss=possss+sis;
}
return;
}
int main(){
cin>>n;
for(int i=1;i<n;++i){
cin>>a>>b;
add(a,b);
add(b,a);
}
DFL(1,0);
// for(int i=1;i<=n;++i) cout<<lfs[i]<<endl;
DFS(1,0,1,lfs[1]);
for(int i=1;i<=n;++i)
cout<<lll[i]<<" "<<rrr[i]<<endl;
return 0;
}