AtCoder Beginner Contest 385(A~F)题解

news/2024/12/23 22:37:39 标签: 算法, 图论, 深度优先

A - Equally

思路:由题可知最多只能分成三组,我们只需要判断是否三个数都相等,或者两个数相加等于另外一个数即可

#include<bits/stdc++.h>
using namespace std;
#define int long long
int n;
string s;
int a,b,c;
signed main()
{
	cin>>a>>b>>c;
	if(a==b+c||b==a+c||c==a+b||(a==b&&b==c))
	{
		cout<<"Yes\n";
	}
	else
	{
		cout<<"No\n";
	}
	return 0;
}

 B - Santa Claus 1

思路:数据很小,直接暴力模拟即可

#include<bits/stdc++.h>
using namespace std;
#define int long long
int n,m,x,y;
char c[105][105];
int vis[105][105];
string t;
int ans=0;
signed main()
{
	cin>>n>>m>>x>>y;
	for(int i=1;i<=n;i++)
	{
		for(int j=1;j<=m;j++)
		{
			cin>>c[i][j];
		}
	}
	cin>>t;
	if(vis[x][y]==0&&c[x][y]=='@')
	{
		vis[x][y]=1;
		ans++;
	}
	for(int i=0;i<t.size();i++)
	{
		if(t[i]=='U'&&c[x-1][y]!='#'&&x-1>=1&&x-1<=n)
		{
			x-=1;
			if(c[x][y]=='@'&&vis[x][y]==0)
			{
				vis[x][y]=1;
				ans++;
			}
		}
		else if(t[i]=='D'&&c[x+1][y]!='#'&&x+1>=1&&x+1<=n)
		{
			x+=1;
			if(c[x][y]=='@'&&vis[x][y]==0)
			{
				vis[x][y]=1;
				ans++;
			}
		}
		else if(t[i]=='L'&&c[x][y-1]!='#'&&y-1>=1&&y-1<=m)
		{
			y-=1;
			if(c[x][y]=='@'&&vis[x][y]==0)
			{
				vis[x][y]=1;
				ans++;
			}
		}
		else if(t[i]=='R'&&c[x][y+1]!='#'&&y+1>=1&&y+1<=m)
		{
			y+=1;
			if(c[x][y]=='@'&&vis[x][y]==0)
			{
				vis[x][y]=1;
				ans++;
			}
		}
	}
	cout<<x<<" "<<y<<" "<<ans;
	return 0;
}

C - Illuminate Buildings

 思路:用map去存储每一个高度的大楼,然后去寻找每一个高度内的最长等差数列即可

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

signed main() {  
    int n;  
    cin >> n;  
    vector<int> heights(n);  
    for (int i = 0; i < n; i++) {  
        cin >> heights[i];  
    }  

    unordered_map<int, vector<int>> index_map;  
    for (int i = 0; i < n; i++) {  
        index_map[heights[i]].push_back(i + 1);  
    }  

    int max_count = 1;  

    for (auto& entry : index_map) {  
        vector<int>& indices = entry.second;  
        int size = indices.size();  

        if (size <= 2) {  
            max_count = max(max_count, size);  
            continue;  
        }  
 
        unordered_set<int> index_set(indices.begin(), indices.end());  


        for (int i = 0; i < size; i++) {  
            for (int j = i + 1; j < size; j++) {  
                int d = indices[j] - indices[i];
                int count = 2;   
                int next_index = indices[j] + d;  

                while (index_set.count(next_index)) { 
                    count++;  
                    next_index += d;  
                }  

                max_count = max(max_count, count);  
            }  
        }  
    }  

    cout << max_count << endl;  
    return 0;  
}

D - Santa Claus 2

 思路:这题和b题唯一的区别就是数据量很大,因此我们在处理这种问题可以考虑将其一行和一列存储起来,因此我们可以用一个map<int,set<int>>去存储,前面的键值表示的是当前行/列,后面的键值表示在当前行/列,set[i]位置上有一个房子,我们去用二分寻找区间,如果碰到房子,就将房子从这两个map的set里面弹出,然后个数+1

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

#define int long long
#define rep(i,n) for(int i=0;i<(int)(n);i++)
void solve()
{
    int n, m;
    int sx, sy;
    cin >> n >> m >> sx >> sy;
    map<int, set<int> > mx, my;
    rep(i, n) {
        int x, y;
        cin >> x >> y;
        mx[x].insert(y);
        my[y].insert(x);
    }
    map<char, int> dx, dy;
    dx['U'] = 0, dx['D'] = 0, dx['L'] = -1, dx['R'] = 1;
    dy['U'] = 1, dy['D'] = -1, dy['L'] = 0, dy['R'] = 0;
    int x = sx, y = sy;
    rep(tt, m) {
        char d;
        int c;
        cin >> d >> c;
        int nx = x + dx[d] * c;
        int ny = y + dy[d] * c;
        if (d == 'U' || d == 'D') {
            if (!mx.count(nx)) {
                x = nx;
                y = ny;
                continue;
            }
            int st = y, ed = ny;
            if (st > ed) swap(st, ed);
            auto l = mx[nx].lower_bound(st);
            auto r = mx[nx].upper_bound(ed);
            if (r == mx[nx].begin()) {
                x = nx;
                y = ny;
                continue;
            }
            vector<int> v;
            for (auto i = l; i != r; i++) {
                v.push_back(*i);
            }
            for (auto i : v) {
                mx[x].erase(i);
                if (my.count(i)) my[i].erase(nx);
            }
        }
        if (d == 'L' || d == 'R') {
            if (!my.count(ny)) {
                x = nx;
                y = ny;
                continue;
            }
            int st = x, ed = nx;
            if (st > ed) swap(st, ed);
            auto l = my[ny].lower_bound(st);
            auto r = my[ny].upper_bound(ed);
            if (r == my[ny].begin()) {
                x = nx;
                y = ny;
                continue;
            }
            vector<int> v;
            for (auto i = l; i != r; i++) {
                v.push_back(*i);
            }
            for (auto i : v) {
                my[y].erase(i);
                if (mx.count(i)) mx[i].erase(ny);
            }
        }
        x = nx;
        y = ny;
    }
    int sum = 0;
    for (auto i : mx) sum += i.second.size();
    cout << x << " " << y << " " << n - sum;
}

signed main()
{
	solve();
}

 E - Snowflake Tree

这题其实并未涉及算法,更多的是思维,首先我们可以发现,根节点连接的点x上的连接的点都是相同的,因此我们的雪花树的深度最大为2(设我们的根节点深度为1),因此我们可以将每一个点的度统计出来,然后遍历每一个点,让每一个点都去当一次根节点,然后,用set去存储其子节点的度-1(表示孙子节点的度),然后从大到小排序,j*(当前节点的度+1),就是能够连接的最多的节点,然后去不断更新最大值即可

#include <bits/stdc++.h>  
using namespace std;  
#define int long long  
int n;  
vector<int> e[300005];  
signed main() {  
    cin >> n;  
    for(int i = 1; i < n; i++) {  
        int u, v;  
        cin >> u >> v;  
        e[u].push_back(v);  
        e[v].push_back(u);  
    }  
    int ans = 0;  

    for(int i = 1; i <= n; i++) {  
        vector<int> a;  
        for(int u : e[i]) {  
            a.push_back(e[u].size() - 1);  
        }  
        sort(a.rbegin(), a.rend());   
        for(int j = 0; j < a.size(); j++) {  
            ans = max(ans, (j + 1) * (a[j]+1) + 1);  
        }  
    }  
    
    cout << n - ans;  
    return 0;  
}

总体来说这场难度不高,f有一个卡精度问题,要用long double,后续更新,最重要的是e的思维 

F - Visible Buildings

 

思路:我们直接从斜率入手算出在y轴上的截距即可, 我们去取y轴上的截距,如果截距最大值都小于0,那么就输出-1,否则就输出截距的最大值

注意精度问题,用long double即可轻易ac掉这道题

#include<bits/stdc++.h>
using namespace std;
#define int long long
int n;
long double x[200005];
long double h[200005];
signed main()
{
	cin>>n;
	for(int i=1;i<=n;i++)
	{
		cin>>x[i]>>h[i];
	}
	long double ans=-LLONG_MAX;
	for(int i=2;i<=n;i++)
	{
		long double xie=(h[i]-h[i-1])/(x[i]-x[i-1]);
		long double jie=h[i]-xie*x[i];
		ans=max(ans,jie);
	}
	if(ans<0)
	{
		cout<<"-1";
	}
	else
	{
		cout<<fixed<<setprecision(10)<<ans<<"\n";
	}
	return 0;
}


http://www.niftyadmin.cn/n/5797082.html

相关文章

MySQL 主从复制与高可用

在现代分布式系统中&#xff0c;数据库的高可用性和可靠性至关重要。MySQL 提供了主从复制&#xff08;Master-Slave Replication&#xff09;机制来实现数据的冗余和容错&#xff0c;保证在主数据库发生故障时能够继续提供服务。而在此基础上&#xff0c;通过进一步的高可用架…

严格推导质点曲线运动的运动学方程

前言 相当一部分物理学书籍在推导质点曲线运动的运动学方程时&#xff0c;采用的都是先建立位移的微元 Δ r ⃗ \Delta \vec{r} Δr &#xff0c;然后几何近似求极限的方法。这种方法虽然能得到正确的结论&#xff0c;但数学上的严格性略有欠缺&#xff0c;且过程繁琐。考虑到…

tomcat的安装以及配置(基于linuxOS)

目录 安装jdk环境 yum安装 验证JDK环境 安装tomcat应用 yum安装 ​编辑 使用yum工具进行安装 配置tomcat应用 关闭防火墙和selinux 查看端口开启情况 ​编辑 访问tomcat服务 安装扩展包 重启服务 查看服务 源码安装 进入tomcat官网进行下载 查找自己要用的to…

html <a>设置发送邮件链接、打电话链接 <a href=“mailto:></a> <a href=“tel:></a>

1.代码 <ul><li>电话&#xff1a;<a href"tel:18888888888">188-8888-8888</a></li><li>邮箱&#xff1a;<a href"mailto:10000qq.com">10000qq.com</a></li><li>邮箱&#xff1a;<a hre…

sql注入之union注入

Sql注入之union注入攻击 今天讲讲sql注入攻击流程 事先声明&#xff0c;本文仅仅作为学习使用&#xff0c;因个人原因导致的后果&#xff0c;皆与本人无关&#xff0c;后果由个人承担。 本次演示靶机为封神台里的题目&#xff0c;具体连接如下 https://hack.zkaq.cn/battle…

<代码随想录> 算法训练营-2024.12.20

322. 零钱兑换 class Solution:def coinChange(self, coins: List[int], amount: int) -> int:# dp[i][j]表示 提供到coins[i]的硬币&#xff0c;总金额为j的最少硬币个数 硬币个数无限&#xff0c;完全背包# 有两种取值&#xff0c;一种是取dp[i-1][j] 另一种是如果j比当前…

HarmonyOS NEXT 技术实践-基于基础视觉服务实现骨骼点识别

本示例展示了如何在HarmonyOS Next中实现基于基础视觉服务的骨骼点识别功能。骨骼点识别是计算机视觉中的一项重要技术&#xff0c;广泛应用于运动分析、健身监控和增强现实等领域。通过使用HarmonyOS Next提供的视觉API&#xff0c;开发者能够轻松地对人物图像进行骨骼点检测&…

反无人机防御系统概述!

一、定义与工作原理 反无人机防御系统是指利用频谱侦测探测、雷达探测、无线电干扰压制等技术实现对非法入侵无人机进行管控防御的系统。它采用多种技术手段&#xff0c;如雷达、光电传感器、红外线探测器等&#xff0c;通过实时监测无人机的位置、速度、航迹、姿态等信息&…