第二十六周代码(总结 + 查缺补漏)

蓝桥云课:刷题数量通过139题,尝试解决(未做出)18题。

  • 其中蓝桥杯往年真题74题,尝试解决(未做出)6题
  • 算法模板题5题
  • 经典算法题20题,尝试解决(未做出)1题
  • 算法赛赛题37题,尝试解决(未做出)11题

力扣:已通过题目5题,提交未通过1题

洛谷:已通过题目31题,尝试解决(未做出)4题

Acwing:4-5题

牛客:已通过题目3题

全部平台共通过题目183题,看看能不能拿省一

2024/04/08        周一

盖印章【算法赛】

题目链接

【参考代码】

#include <bits/stdc++.h>
using namespace std;

//a+b = k
//3a+2b = 1的总数(count1)
int main() //解方程,数论
{
    int n,m,k;
    cin>>n>>m>>k;
    int count1 = 0;
    for(int i=0; i<n*m; i++)
    {
        char c;
        cin>>c;
        if(c == '1')
            count1++;
    }
    cout << count1 - 2*k << ' ' << 3*k - count1 << endl;
    return 0;
}

字符迁移【算法赛】

题目链接

【参考代码】

暴力66.7%,使用多行注释那段无法通过。

#include <bits/stdc++.h>
using namespace std;

int main() //暴力66.7%
{
    int n, q;
    cin>>n>>q;
    string s;
    cin>>s;
    while(q--)
    {
        int l, r, k;
        cin>>l>>r>>k;
        for(int i=l-1; i<=r-1; i++)
        {
            //因为z的ASCII码是122,ASCII码的最大值是127,
            //假设起始值是z,+25,ASCII码值的计算中很容易出界。所以需要先减去'a'保证不会出界
            s[i] = 'a' + (s[i] - 'a' + k) % 26; 
            /*
            s[i] += k % 26;
            
            if(s[i] >= 'z')
                s[i] = s[i] - 26;
            */
        }
    }
    cout << s << endl;
    return 0;
}

2024/04/10        周三

城市规划(kruskal算法)

题目链接

【参考代码】 

//kruskal算法
#include <bits/stdc++.h>
using namespace std;

const int N = 2001; // 定义常量N为2001,表示城市数量的最大值
int f[N], X[N], Y[N]; // 定义并查集数组f,以及城市的X和Y坐标数组
long long result = 0; // 定义结果变量result,用于存储最小生成树的总权值

int find(int index) // 查找函数,用于查找并查集中的根节点
{
    if(f[index] != index) // 如果当前节点不是根节点
        return f[index] = find(f[index]); // 递归查找根节点,并进行路径压缩
    return index; // 返回根节点
}

int getDistance(int x1, int x2, int y1, int y2) // 计算两个城市之间的距离
{
    return abs(x1-x2) + abs(y1-y2); // 返回两点之间的曼哈顿距离
}

struct node // 定义结构体node,表示边的信息
{
    int from; // 起点城市编号
    int to; // 终点城市编号
    int distance; // 边的权值(距离)
    node(int num1, int num2, int num3) // 构造函数,初始化城市编号和距离
    {
        from = num1;
        to = num2;
        distance = num3;
    }
};

bool compare(node e1, node e2) // 比较函数,用于对边进行排序
{
    return e1.distance < e2.distance; // 按照距离从小到大排序
}

vector<node> v; // 定义向量v,用于存储所有的边
set< pair<int, int> > set1; // 定义集合set1,用于存储关系不好的城市对

int main()
{
    int n, k,x,y; // 定义变量n、k、x、y,分别表示城市对数量、关系不好的城市对数量、城市坐标xy
    cin >> n >> k; // 输入城市数量和关系不好的城市对数量
    for(int i=1;i<=n;i++) // 循环输入每个城市的坐标
    {
        cin>>X[i]>>Y[i];
    } 
    while(k--) // 输入k个关系不好的城市并插入set 
    {
        cin>>x>>y; // 输入关系不好的城市对
        set1.insert(make_pair(x, y)); // 将城市对插入集合set1中
        set1.insert(make_pair(y, x)); // 注意这里也要插入反向的城市对,因为无向图是双向的
    }
    //并查集初始化
    for(int i=1; i<=n; i++) // 初始化并查集,每个节点的父节点都是自己
    {
        f[i] = i;
    }
    for(int i=1; i<=n; i++) // 遍历所有城市的组合
    {
        for(int j=i+1; j<=n; j++) // 注意这里是从i+1开始,避免重复计算和自环的情况
        {
            if(set1.find(make_pair(i, j) ) != set1.end() || set1.find(make_pair(j, i) ) != set1.end()) // 如果这两个城市是关系不好的城市对,则跳过
                continue;
            int dis = getDistance(X[i], X[j], Y[i], Y[j]); // 计算两个城市之间的距离
            v.push_back(node(i, j, dis) ); // 将边的信息存入向量v中
            v.push_back(node(j, i, dis) ); // 注意这里也要插入反向的边,因为无向图是双向的
        }
    }
    sort(v.begin(), v.end(), compare); // 对所有边按照距离进行排序
    for(auto &e: v) // 遍历所有的边
    {
        int boss1 = find(e.from); // 查找起点城市的根节点
        int boss2 = find(e.to); // 查找终点城市的根节点
        if(boss1 == boss2) // 如果两个城市已经在同一个连通分量中,则跳过这条边
            continue;
        f[boss1] = boss2; // 合并两个连通分量,即将一个城市的根节点指向另一个城市的根节点
        result += e.distance; // 累加边的权值到结果变量result中
    }
    cout << result << endl; // 输出最小生成树的总权值
    return 0;
}

修建公路(kruskal算法 & prim算法)

题目链接

【参考代码】

kruskal算法

//kruskal算法
#include <bits/stdc++.h>
using namespace std;

const int N = 3e5+1; // 定义常量N为300001
int f[N]; // 定义数组f,用于存储并查集的父节点信息

// 查找函数,用于查找元素index的根节点
int find(int index)
{
    if(f[index] != index) // 如果当前元素的父节点不是它自己
        return f[index] = find(f[index]); // 递归查找父节点,并将结果赋值给当前元素
    return index; // 返回当前元素的根节点
}

// 定义结构体node,表示边的信息
struct node
{
    int from; // 起点
    int to; // 终点
    int distance; // 距离
}edge[N]; // 定义数组edge,用于存储所有的边

// 比较函数,用于比较两个边的距离大小
bool compare(node e1, node e2)
{
    return e1.distance < e2.distance;
}

int main()
{
    int n, m, u, v, w;
    cin >> n >> m; // 输入点的数量n和边的数量m
    for(int i=1;i<=m;i++) // 输入每条边
    {
        cin>>edge[i].from>>edge[i].to>>edge[i].distance;  
    } 
    // 初始化并查集,将每个点的父节点设置为它自己
    for(int i=1; i<=n; i++)
    {
        f[i] = i;
    }
  
    // 根据边的距离对边进行排序
    sort(edge+1, edge+1+m, compare);
    long long result = 0, roadcount = 0; // 初始化结果result和道路数量roadcount
    for(int i=1; i<=m; i++) // 遍历每条边
    {
        int boss1 = find(edge[i].from); // 查找起点的根节点
        int boss2 = find(edge[i].to); // 查找终点的根节点
        if(boss1 == boss2) // 如果起点和终点在同一个集合中,跳过这条边
            continue;
        f[boss1] = boss2; // 合并两个集合
        result += edge[i].distance; // 累加边的距离
        roadcount++; // 道路数量加1
    }
    if(roadcount < n-1) // 如果道路数量小于n-1,输出-1
        cout << -1 << endl;
    else
        cout << result << endl; // 输出结果result
    return 0;
}

prim算法

//Prim算法
#include <bits/stdc++.h> // 引入C++标准库
using namespace std; // 使用标准命名空间
typedef long long ll; // 定义长整型别名ll
const ll INF = 0x3f3f3f3f3f3f3f3fll; // 定义无穷大常量
const int N = 1e5+10; // 定义节点数量上限
bool visit[N]; // 定义访问标记数组
ll distance1[N]; // 定义距离数组
ll ans = 0; // 定义答案变量

// 定义边的结构体
struct edge{
    int id; // 边的终点
    ll weight; // 边的权重
    edge(int num1, ll num2) // 构造函数
    {
        id = num1;
        weight = num2;
    }
    bool operator < (const edge &e1) const{ // 重载小于运算符,用于优先队列的比较
        return e1.weight < weight;
    }
};

vector<edge> e[N]; // 定义边的向量数组

// Prim算法实现
ll prim(int n, int start)
{
    memset(distance1, 0x3f, sizeof(distance1)); // 初始化距离数组为无穷大
    priority_queue<edge> q; // 定义优先队列
    q.push(edge(start, 0)); // 将起始点加入优先队列
    distance1[start] = 0; // 起始点到自身的距离为0
    while(!q.empty()) // 当优先队列不为空时
    {
        edge u = q.top(); // 取出队首元素
        q.pop(); // 弹出队首元素
        if(visit[u.id] == true) // 如果该点已被访问过,则跳过
            continue;
        visit[u.id] = true; // 标记该点已被访问
        ans += u.weight; // 累加权重
        for(int i=0; i<e[u.id].size(); i++) // 遍历与该点相连的所有边
        {
            int v = e[u.id][i].id; // 获取终点
            ll w = e[u.id][i].weight; // 获取权重
            if(visit[v] == true) // 如果终点已被访问过,则跳过
                continue;
            if(w < distance1[v]) // 如果当前权重小于已知的最小权重,则更新距离数组
            {
                distance1[v] = w;
                q.push(edge(v, distance1[v])); // 将新的点加入优先队列
            }           
        }
    }
    for(int i=1; i<=n; i++) // 检查是否所有点都被访问过
    {
        if(visit[i] == false) // 如果有未被访问过的点,返回-1
            return -1;
    }
    return ans; // 返回最小生成树的权重和
}

int main() // 主函数
{
    int n, m; // 定义节点数和边数
    cin>>n>>m; // 输入节点数和边数
    while(m--) // 根据边数循环输入边的信息
    {
        int x, y; // 定义边的起点和终点
        ll d; // 定义边的权重
        cin>>x>>y>>d; // 输入边的信息
        e[x].push_back(edge(y, d)); // 将边加入起点的边向量中
        e[y].push_back(edge(x, d)); // 将边加入终点的边向量中
    }
    cout << prim(n, 1) << endl; // 输出Prim算法的结果
    return 0; // 程序结束
}

2024/04/12        周五

P5716 【深基3.例9】月份天数

题目链接

【参考代码】

#include <bits/stdc++.h>
using namespace std;

int day[] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};

void leapyear(int year)
{
	if(year % 4 == 0 && year % 100 != 0 || year % 400 == 0)
		day[2] = 29;  //2月天数改29
	else
		day[2] = 28;
}

int main()
{
	int year, month;
	cin>>year>>month;
	leapyear(year);
	cout << day[month] << endl;
}

分解质因数

题目链接

【参考代码】

#include <stdio.h>

int isprime(int n) //判断是否为质数
{
    int i;
    for (i = 2; i < n; i++)
    {
        if (n % i == 0)
            return 0;
    }
    return 1;
}

int main()
{
    int amin = 0;
    int bmax = 0;
    int i = 0;
    int j = 0;
    int count = 0;

    scanf("%d %d", &amin, &bmax);

    for (i = amin; i <= bmax; i++)
    {
        if (isprime(i)) //直接判断是否为质数
        {
            printf("%d=%d\n", i, i);
        }
        else
        {
            int tmp = i;
            printf("%d=", i);
            for (j = 2; j < tmp; j++) //等于号补上
            {
                
                if (tmp % j == 0 && isprime(j))
                {
                    tmp /= j;
                    printf("%d*", j);
                    j=1; //因为在循环末尾需要+1,j=1+1=2
                }
                
            }
            printf("%d\n", tmp);
        }
    }
}

生日蜡烛

题目链接

【参考代码】

#include <iostream>
using namespace std;
//有很多问题,比如说1/2计算机不会算
//两个变量a1和n放在一起,a1*n也出问题

//两个循环判断范围,假设情况:
//第一次循环1-100,第二次2-50,第三次3-25......
int main() {
	int n = 1;
	int i, j, sum = 0;
	for (i = 1; i <= 100; i++) {
		for (j = i; j <= 100; j++) {
			sum += j;
			if (sum == 236)
			{
				cout << i;
				break;
			}
		}
		sum = 0;
	}
}

相关推荐

  1. C复习--更新中

    2024-04-12 23:46:01       37 阅读

最近更新

  1. TCP协议是安全的吗?

    2024-04-12 23:46:01       18 阅读
  2. 阿里云服务器执行yum,一直下载docker-ce-stable失败

    2024-04-12 23:46:01       19 阅读
  3. 【Python教程】压缩PDF文件大小

    2024-04-12 23:46:01       19 阅读
  4. 通过文章id递归查询所有评论(xml)

    2024-04-12 23:46:01       20 阅读

热门阅读

  1. Object.assign详解

    2024-04-12 23:46:01       13 阅读
  2. c++成绩排名

    2024-04-12 23:46:01       15 阅读
  3. js中如何进行隐式类型转换

    2024-04-12 23:46:01       14 阅读
  4. 【5】c++多线程技术之线程间通信

    2024-04-12 23:46:01       14 阅读
  5. 个人博客项目笔记_02

    2024-04-12 23:46:01       14 阅读
  6. 【C语言】- C语言字符串函数详解

    2024-04-12 23:46:01       13 阅读
  7. 飞机降落(蓝桥杯)

    2024-04-12 23:46:01       20 阅读
  8. 电机驱动专题-理论学习-计算整数化

    2024-04-12 23:46:01       16 阅读
  9. Android中,TextView跑马灯(marquee)问题

    2024-04-12 23:46:01       17 阅读