来写一下蒟蒻第一次ak的题
我是菜鸡
A 声控灯
这个题就是各种条件的判断,一开始有些情况没想到,写了四五遍才过,最后删掉一些不必要的语句加上优化跑了1ms
至于大佬们0ms我办不到了我太难了
情况大概有这些
m >= 1 && m <= 3所以可以从m开始分类讨论
当 m == 1 时,由于题目说一定符合实际情况,所以这个时候 n 只能等于1,这个时候答案 ans = 1
当 m == 2 时,我们很容易就能想到当小明在一楼或者顶楼的时候是亮两个灯的。但是还有一种答案不确定的情况,在这个地方卡了我两次 就是如果一共只有两层楼呢,这个时候亮两个灯也是合理的,但是在这个时候,我们无法得出小明到底在几楼,你说他在一楼可以,说他在二楼也可以。
当 m == 3 时,这个时候直接就可以得出小明在中间的那个楼层,又因为题目说一定符合实际情况,所以不用判断这三个数是否相差1
这样代码就写出来了,经过优化蒟蒻的代码也终于跑到了1ms
int T,n,m;
int a[5];
int ans;
int main(){
io >> T;
while(T--){
io >> n >> m;
for(int i=1;i<=m;i++) io >> a[i];
if(m == 1 && n == 1) ans = 1;
else if(m == 2){
if(n == 2) ans = -1;
else{
if(a[1] == 1 && a[2] == 2) ans = 1;
else if(a[1] == n-1 && a[2] == n) ans = n;
}
}
else ans = a[2];
printf("%d\n",ans);
}
return 0;
}
B 构造字符串
一道思维题吧
ll n,x;
int main(){
scanf("%d",&n);
ll sum = 0;
for(int i=0;i<26;i++){
scanf("%d",&x);
sum += x/n;
}
cout << sum << endl;
return 0;
}
C 情报战
一开始直接按照题目的思路去写,结果只得了20分,后来就开始想用数据结构来优化,突然发现可以用并查集来实现。
我只需要把我知道的数存在一个集合中,让他成为一棵树。每次去判断给出的x的根节点是否已经存在于这棵树中,存在的话就说明我已经知道这个数,不存在的话就更新答案。同理当给出 x 和 y 的和时,如果 x 的根节点存在 y 的根节点不存在,我们就可以得出 y 的值,所以更新答案;如果 y 的根节点存在而 x 的根节点不存在,我们就可以得出 x 的值,此时更新答案。每次输出这个答案即可
关于并查集的理解和一些操作
强推一下b站大佬的视频,讲的巨仔细
传送门
int n,m,fa[maxn],sz[maxn],vis[maxn];
int find(int x){
return fa[x] = fa[x] == x ? x : find(fa[x]);
}
void Union(int x,int y){
int fx = find(x) , fy = find(y);
if(fx != fy){
fa[fx] = fy;
sz[fy] += sz[fx];
if(vis[fx]) vis[fy] = 1;
}
}
int main(){
io >> n >> m;
for(int i=1;i<=n;i++){
fa[i] = i;
sz[i] = 1;
}
int op,x,y,ans = 0;
while(m--){
io >> op >> x;
if(op == 1){
int fx = find(x);
if(vis[fx] == 0){
ans += sz[fx];
vis[fx] = 1;
}
}else{
io >> y;
if(x == y){
int fx = find(x);
if(vis[fx] == 0){
ans += sz[fx];
vis[fx] = 1;
}
}else{
int fx = find(x) , fy = find(y);
if(vis[fx] == 0 && vis[fy] == 1){
ans += sz[fx];
}else if(vis[fx] == 1 && vis[fy] == 0){
ans += sz[fy];
}
Union(x,y);
}
}
printf("%d\n",ans);
}
return 0;
}