2025.4.30

P8655 [蓝桥杯 2017 国 B] 发现环

题目描述

小明的实验室有 $N$ 台电脑,编号 $1 \sim N$。原本这 $N$ 台电脑之间有 $N-1$ 条数据链接相连,恰好构成一个树形网络。在树形网络上,任意两台电脑之间有唯一的路径相连。

不过在最近一次维护网络时,管理员误操作使得某两台电脑之间增加了一条数据链接,于是网络中出现了环路。环路上的电脑由于两两之间不再是只有一条路径,使得这些电脑上的数据传输出现了 BUG。

为了恢复正常传输。小明需要找到所有在环路上的电脑,你能帮助他吗?

输入格式

第一行包含一个整数 $N$。

以下 $N$ 行每行两个整数 $a$ 和 $b$,表示 $a$ 和 $b$ 之间有一条数据链接相连。

输入保证合法。

输出格式

按从小到大的顺序输出在环路上的电脑的编号,中间由一个空格分隔。

输入输出样例 #1

输入 #1

5
1 2
3 1
2 4
2 5
5 3

输出 #1

1 2 3 5

说明/提示

对于 $30%$ 的数据,$1 \le N \le 1000$。

对于 $100%$ 的数据,$1 \le N \le 10^5$,$1 \le a,b \le N$。

时限 1 秒, 256M。蓝桥杯 2017 年第八届国赛

#include<bits/stdc++.h>
using namespace std;
const int N=2e5+10;
int d[N];
int h[N],ne[N],to[N],idx=0;
void add(int a,int b){
    to[++idx]=b;
    ne[idx]=h[a];
    h[a]=idx;
}
int main(){
    int n;
    cin>>n;
    unordered_set<int> s;
    memset(h,-1,sizeof h);
    for(int i=1;i<=n;i++){
        int u,v;
        cin>>u>>v;
        d[u]++,d[v]++;
        add(u,v);
        add(v,u);
    }
    queue<int> q;
    for(int i=1;i<=n;i++)
        if(d[i]==1) q.push(i),s.insert(i);
    while(q.size()){
        int u=q.front();
        q.pop();
        for(int i=h[u];~i;i=ne[i]){
            int v=to[i];
            if(--d[v]==1){
                q.push(v);
                s.insert(v);
            }
        }
    }
    for(int i=1;i<=n;i++)
        if(s.find(i)==s.end()) cout<<i<<' ';
    return 0;
}

P8669 [蓝桥杯 2018 省 B] 乘积最大

题目描述

给定 $N$ 个整数 $A_1, A_2,\cdots, A_N$。请你从中选出 $K$ 个数,使其乘积最大。

请你求出最大的乘积,由于乘积可能超出整型范围,你只需输出乘积除以 $1000000009$(即 $10^9+9$)的余数。

注意,如果 $X<0$, 我们定义 $X$ 除以 $1000000009$ 的余数是 $0-((0-x)\bmod 1000000009)$。

输入格式

第一行包含两个整数 $N$ 和 $K$。

以下 $N$ 行每行一个整数 $A_i$。

输出格式

一个整数,表示答案。

输入输出样例 #1

输入 #1

5 3 
-100000   
-10000   
2   
100000  
10000

输出 #1

999100009

输入输出样例 #2

输入 #2

5 3 
-100000   
-100000   
-2   
-100000  
-100000

输出 #2

-999999829

说明/提示

对于 $40%$ 的数据,$1\le K\le N\le 100$。

对于 $60%$ 的数据,$1\le K \le 1000$。

对于 $100%$ 的数据,$1\le K\le N\le 105$,$-105\le A_i\le 10^5$。

#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N=1e5+10,mod=1e9+9;
int a[N];
int n,k;
signed main(){
    cin>>n>>k;
    for(int i=1;i<=n;i++) cin>>a[i];
    sort(a+1,a+n+1);
    int ans=1;
    int l=1,r=n;
    if(k%2) ans*=a[n],r=n-1;
    k/=2;
    int f=ans<0? -1:1;
    for(int i=1;i<=k;i++){
        if(a[l]*a[l+1]*f>a[r]*a[r-1]*f) ans=ans%mod*a[l]%mod*a[l+1]%mod,l+=2;
        else ans=ans%mod*a[r]%mod*a[r-1]%mod,r-=2;
    }
    cout<<ans%mod<<endl;
    return 0;
}

P8663 [蓝桥杯 2018 省 A] 倍数问题

题目描述

众所周知,小葱同学擅长计算,尤其擅长计算一个数是否是另外一个数的倍数。但小葱只擅长两个数的情况,当有很多个数之后就会比较苦恼。现在小葱给了你 $n$ 个数,希望你从这 $n$ 个数中找到三个数,使得这三个数的和是 $K$ 的倍数,且这个和最大。数据保证一定有解。

输入格式

从标准输入读入数据。

第一行包括 $2$ 个正整数表示 $n$ 和 $K$。

第二行 $n$ 个正整数,代表给定的 $n$ 个数。

输出格式

输出一行一个整数代表所求的和。

输入输出样例 #1

输入 #1

4 3
1 2 3 4

输出 #1

9

说明/提示

【样例解释】

选择 $2$、$3$、$4$。

【数据约定】

对于 $30%$ 的数据,$n \le 100$。

对于 $60%$ 的数据,$n \le 1000$。

对于另外 $20%$ 的数据,$K \le 10$。

对于 $100%$ 的数据,$1 \le n \le 10^5$,$1 \le K \le 10^3$,给定的 $n$ 个数均不超过 $10^8$。

时限 1 秒,256M。蓝桥杯 2018 年第九届省赛。

#include<bits/stdc++.h>
using namespace std;
int main(){
    int n,k;
    cin>>n>>k;
    vector<vector<int>> v(k); 
    for(int i=1;i<=n;i++){
        int x;
        cin>>x;
        v[x%k].push_back(x);
    }
    for(int i=0;i<k;i++)
        sort(v[i].begin(),v[i].end());
    int ans=0;
    for(int i=0;i<k;i++){
        for(int j=i+1;j<k;j++){
            int e=(2*k-i-j)%k;
            int len1=v[i].size();
            int len2=v[j].size();
            int len3=v[e].size();
            if(e!=i&&e!=j){
                if(len1<1||len2<1||len3<1) continue;
                ans=max(ans,v[i].back()+v[j].back()+v[e].back());
            }
            else if(e==i){
                if(len1<2||len2<1) continue;
                ans=max(ans,v[j][len2-1]+v[i][len1-1]+v[i][len1-2]);
            }
            else if(e==j){
                if(len1<1||len2<2) continue;
                ans=max(ans,v[i][len1-1]+v[j][len2-1]+v[j][len2-2]);
            }
            else{
                if(len1<3) continue;
                ans=max(ans,v[i][len1-3]+v[i][len1-1]+v[i][len1-2]);
            }
        }
    }
    cout<<ans<<endl;
    return 0;
}

P8712 [蓝桥杯 2020 省 B1] 整数拼接

题目描述

给定一个长度为 $n$ 的数组 $A_1,A_2,\cdots,A_n$。你可以从中选出两个数 $A_i$ 和 $A_j$($i\neq j$),然后将 $A_i$ 和 $A_j$ 一前一后拼成一个新的整数。例如 12345 可以拼成 1234534512。注意交换 $A_i$ 和 $A_j$ 的顺序总是被视为 $2$ 种拼法,即便是 $A_i=A_j$ 时。

请你计算有多少种拼法满足拼出的整数是 $K$ 的倍数。

输入格式

第一行包含 $2$ 个整数 $n$ 和 $K$。

第二行包含 $n$ 个整数 $A_1,A_2,\cdots,A_n$。

输出格式

一个整数代表答案。

输入输出样例 #1

输入 #1

4 2
1 2 3 4

输出 #1

6

说明/提示

对于所有评测用例,$1\le n\le10^5$,$1\le k\le10^5$,$1\le A_i\le10^9$。

蓝桥杯 2020 第一轮省赛 B 组 I 题。

#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N=1e6+10;
int mp[11][N];
int a[N];
signed main(){
    int n,k;
    cin>>n>>k;
    for(int i=1;i<=n;i++) cin>>a[i];
    for(int i=1;i<=n;i++){
        int t=10;
        for(int j=1;j<=10;j++){
            // cout<<a[i]%k*t%k<<endl;
            mp[j][a[i]%k*t%k]++;
            t=t*10%k;
        }
    }
    int ans=0;
    for(int i=1;i<=n;i++){
        int len=to_string(a[i]).size();
        ans+=mp[len][((-a[i])%k+k)%k];
    }
    for(int i=1;i<=n;i++){
        int num=stoll(to_string(a[i])+to_string(a[i]));
        if(num%k==0) ans-=1;
    }
    cout<<ans<<endl;
    return 0;
}

特别需要注意的是需要使用stoll()而不是stoi(),stoi()

stoi 函数是 C++ 标准库中用于将字符串转换为整数的函数。它可以处理不同进制的数字字符串,并将其转换为十进制整数。如果字符串包含非数字字符,stoi将抛出 invalid_argument 异常;如果转换后的数字超出 int 类型的范围,将抛出 out_of_range 异常

P8708 [蓝桥杯 2020 省 A1] 整数小拼接

题目描述

给定一个长度为 $n$ 的数组 $A_1,A_2,\cdots,A_n$。你可以从中选出两个数 $A_i$ 和 $A_j$($i\neq j$),然后将 $A_i$ 和 $A_j$ 一前一后拼成一个新的整数。例如 12345 可以拼成 1234534512。注意交换 $A_i$ 和 $A_j$ 的顺序总是被视为 $2$ 种拼法,即便是 $A_i=A_j$ 时。

请你计算有多少种拼法满足拼出的整数小于等于 $K$。

输入格式

第一行包含 $2$ 个整数 $n$ 和 $K$。

第二行包含 $n$ 个整数 $A_1,A_2,\cdots,A_n$。

输出格式

一个整数代表答案。

输入输出样例 #1

输入 #1

4 33
1 2 3 4

输出 #1

8

说明/提示

对于 $30%$ 的评测用例 $1\le n\le1000$,$1\le k\le10^8$,$1\le A_i\le10^4$。

对于所有评测用例,$1\le n\le10^5$,$1\le k\le10^{10}$,$1\le A_i\le10^9$。

蓝桥杯 2020 第一轮省赛 A 组 H 题。

#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N=1e6+10;
int a[N];
signed main(){
    int n,k;
    cin>>n>>k;
    for(int i=1;i<=n;i++) cin>>a[i];
    sort(a+1,a+n+1);
    int l=1,r=n;
    int ans=0;
    while(l<=r){
        int num=stoll(to_string(a[l])+to_string(a[r]));
        if(num<=k) ans+=(r-l),l++;
        else r--;
    }
    l=1,r=n;
    while(l<=r){
        int num=stoll(to_string(a[r])+to_string(a[l]));
        if(num<=k) ans+=(r-l),l++;
        else r--;
    }
    cout<<ans<<endl;
    return 0;
}

P8744 [蓝桥杯 2021 省 A] 左孩子右兄弟

题目描述

对于一棵多叉树,我们可以通过“左孩子右兄弟”表示法,将其转化成一棵二叉树。

如果我们认为每个结点的子结点是无序的,那么得到的二叉树可能不唯一。换句话说,每个结点可以选任意子结点作为左孩子,并按任意顺序连接右兄弟。

给定一棵包含 $N$ 个结点的多叉树,结点从 $1$ 至 $N$ 编号,其中 $1$ 号结点是根,每个结点的父结点的编号比自己的编号小。请你计算其通过"左孩子右兄弟"表示法转化成的二叉树,高度最高是多少。(只有根结点这一个结点的树高度为 $0$)

例如如下的多叉树:

可能有以下 $3$ 种 (这里只列出 $3$ 种, 并不是全部) 不同的 “左孩子右兄弟” 表示:

其中最后一种高度最高, 为 $4$。

输入格式

输入的第一行包含一个整数 $N$ 。

以下 $N-1$ 行, 每行包含一个整数, 依次表示 $2$ 至 $N$ 号结点的父结点编号。

输出格式

输出一个整数表示答案。

输入输出样例 #1

输入 #1

5
1
1
1
2

输出 #1

4

说明/提示

对于 $30 %$ 的评测用例,$1 \leq N \leq 20$;

对于所有评测用例,$1 \leq N \leq 10^5$ 。

蓝桥杯 2021 第一轮省赛 A 组 H 题。

#include<bits/stdc++.h>
using namespace std;
const int N=2e5+10;
int n;
int h[N],ne[N],to[N],idx=0;
void add(int a,int b){
    to[++idx]=b;
    ne[idx]=h[a];
    h[a]=idx;
}
int dfs(int u){
    int cnt_child=0;
    int max_sub_depth=1;
    for(int i=h[u];~i;i=ne[i]){
        cnt_child++;
        int v=to[i];
        max_sub_depth=max(max_sub_depth,dfs(v));
    }
    if(cnt_child==0) return 1;
    else return max_sub_depth+cnt_child;
}
int main(){
    int n;
    cin>>n;
    memset(h,-1,sizeof h);
    for(int i=2;i<=n;i++){
        int x;cin>>x;
        add(x,i);
    }
    cout<<dfs(1)-1<<endl;
    return 0;
}
posted @ 2025-05-01 10:37  dlNie  阅读(27)  评论(0)    收藏  举报