今天是疯狂赶DDL的一天,之前没补的题都是要还的wwww
我超喜欢这种三题的比赛,害!简单明了,多舒服啊。
心情好,就把三题都写一下吧~
第一题
小明正在上楼梯,当小明逐渐接近某层楼的时候,这层楼的声控灯检测到小明的脚步声便会亮起来,当小明逐渐远去的时候,声控灯由于一段时间内没检测到声音又会灭下去。
由于小明是匀速上楼的,而且他的速度把控得刚刚好,脚步声的音量也十分恰当,使得灯的亮灭呈现出这样的状态:他当前所在的楼层的声控灯是亮起的,他即将抵达的下一层楼的声控灯是亮起的,他刚刚离开的那层楼的声控灯也是亮起的。
现在你站在楼的外面,通过窗户看到了灯的亮灭状态,请推断小明现在在几楼?
讲道理,这题是真的简单,但是唯一就是要多考虑一下,因为给一条筋的朋友萌设了障碍,绕过去就是满分。因为我们脑海中默认的楼房都是三层以上,那么就适用——要么亮两层要么亮三层的规则,但是你不能歧视别墅或者复式楼啊,如果只有一层楼,那么再怎么样都是亮一盏灯,两层楼同理。这里就是一个小小的脑筋急转弯,打破定势思维。
#include<bits/stdc++.h>
using namespace std;
long long n;
int T, m; //T个样例,n层,m盏灯亮起
long long s1, s2, s3; //亮起的层数
int main(){
cin>>T;
while(T--){
cin>>n>>m;
if(n == 1){
for(int i =0 ; i < m; i++) cin>>s1;
cout<<"1"<<endl;continue;
}else if(n == 2){
for(int i =0 ; i < m; i++) cin>>s1;
cout<<"-1"<<endl;continue;
}else if(n >= 3){
if(m == 1){
cin>>s1;
cout<<"-1"<<endl;continue;
}else if(m == 2){
cin>>s1>>s2;
if(s1 == 1 && s2 == 2) {
cout<<"1"<<endl;continue;
}else if(s1 == n - 1 && s2 == n){
cout<<n<<endl; continue;
}else{
cout<<"-1"<<endl;continue;
}
}else if(m ==3){ //m=3
cin>>s1>>s2>>s3;
if(s1 >= 1 && s2 == s1 + 1 && s3 == s2 + 1 && s3 <= n) cout<<s2<<endl;
else cout<<"-1"<<endl;
}
}
}
return 0;
}
第二题
别看它长,其实灰常简单,就是最简单的贪心思维,但是!这题我还是只得了70’,当时自以为有东西没考虑到就没有再管,但是!当事人现在就是后悔,特别地后悔,居然是因为int存不下答案,风暴哭泣!这种愚蠢到极致的错误已经两次了!
风暴哭泣!这样的错误再犯我是小🐕
#include<bits/stdc++.h>
using namespace std;
int alphabet[26]; //字母表
int n; //字符串个数
long long ans; //最长前缀长度,人生苦短,我用long long
int main(){
cin>>n;
for (int i = 0; i < 26; ++i) {
cin>>alphabet[i];
if(alphabet[i] >= n){
ans += alphabet[i] / n;
alphabet[i] -= (alphabet[i] / n) * n;
}
}
cout<<ans<<endl;
return 0;
}
第三题
这题,并查集,而且每次合并只需要合并数量,不需要具体数值。
详细说明见注释——
#include <stdio.h>
using namespace std;
const int N = 3e5 + 10;
int father[N];
bool vis[N];
int data[N];
int Find(int x){
if(x == father[x]) return x;
int a = x;
while(x != father[x]) x = father[x]; //找到x的根结点
while(a != x){ //路径压缩
father[a] = x;
a = father[a];
}
return x;
}
//并不需要具体的集合元素,只需要知道集合中每个元素的个数,那么合并时只需合并数目
int main(){
int n, m, op, x, y, ans=0;
scanf("%d%d",&n, &m);
for (int i = 1;i <= n; i++)
father[i] = i, data[i] = 1;
while (m--){
scanf("%d",&op);
if(op == 1){
scanf("%d", &x);
int fx = Find(x);
if(!vis[fx]){ //此根节点没访问过
ans += data[fx];//累加到答案中
vis[fx] = 1; //标注为访问过
}
}else{
scanf("%d%d", &x, &y);
int fx = Find(x),fy = Find(y); //找到各自的爸爸
if (x == y || vis[fx] || vis[fy]){ //防止已访问过
if (!vis[fx]){
ans += data[fx];
vis[fx] = 1;
}
if (!vis[fy]){
ans += data[fy];
vis[fy] = 1;
}
}
if(fx != fy){ //合并
father[fy] = fx; //认个爸爸
data[fx] += data[fy]; //数量合并即可
}
}
printf("%d\n",ans);
}
return 0;
}
呼——又是高产 赶任务的一天呢!悄咪咪放一张狗子ο(=•ω<=)ρ⌒☆