草庐IT

【牛客小白月赛69】题解与分析A-F【蛋挞】【玩具】【开题顺序】【旅游】【等腰三角形(easy)】【等腰三角形(hard)】

Eriktse Runtime 2023-03-28 原文

比赛传送门:https://ac.nowcoder.com/acm/contest/52441

感觉整体难度有点偏大。

? 作者:Eriktse
? 简介:19岁,211计算机在读,现役ACM银牌选手?力争以通俗易懂的方式讲解算法!❤️欢迎关注我,一起交流C++/Python算法。(优质好文持续更新中……)?
? 个人博客:www.eriktse.com

A-蛋挞

签到题。

只需比较a / ba % b的大小即可。注意开longlong。

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

signed main()
{
    int a, b;scanf("%lld %lld", &a, &b);
    if(a / b < a % b)printf("niuniu eats more than others");
    else if(a / b > a % b)printf("niuniu eats less than others");
    else printf("same");
    return 0;
}

B-玩具

排序贪心。

因为我们要将n个玩具全部买下,所以我们免单的玩具价格越高越好,我们将整个数组排升序后从后往前两个两个拿,且只付更高价格的玩具的钱

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

const int maxn = 1e6 + 9;
int a[maxn];
signed main()
{
    int n;scanf("%lld", &n);
    for(int i = 1;i <= n; ++ i)scanf("%lld", a + i);
    sort(a + 1,a + 1 + n);
    
    int ans = 0;
    for(int i = n;i >= 1; -- i)
    {
        ans += a[i];
        i --;
    }
    printf("%lld\n", ans);
    return 0;
}

C-开题顺序

dfs。

题目数量比较小,我们可以枚举出所有的开题顺序,然后计算出最终分数取大即可,注意剪枝,当时间超过t的时候可以直接结束,此时的分数已经无效了。

#include <bits/stdc++.h>
#define int long long
using namespace std;
const int maxn = 15;
int a[maxn], b[maxn], c[maxn], x[maxn], y[maxn];
int n, t, p;

bitset<maxn> vis;

//当前正在选第dep道题
int dfs(int dep, int ti, int sc)
{
    if(ti > t)return 0;//当累计做题时间已经超过了t说明比较已经结束了
    if(dep == n + 1)return sc;
    
    int res = sc;
    
    for(int i = 1;i <= n; ++ i)
    {
        if(vis[i])continue;
        //切了第i道题
        ti += x[i];
        vis[i] = true;
        res = max(res, dfs(dep + 1, ti, sc + max(c[i], a[i] - ti * b[i] - y[i] * p))); 
        vis[i] = false;
        ti -= x[i];
    }
    return res;
}

signed main()
{
    scanf("%lld %lld %lld", &n, &t, &p);
    for(int i = 1;i <= n; ++ i)
        scanf("%lld %lld %lld %lld %lld", a + i, b + i, c + i, x + i, y + i);

    printf("%lld\n", dfs(1, 0, 0));
    return 0;
}

D-旅游

最小生成树(并查集) + 二分。

首先我们知道要使得所有点互联,且边权尽可能小,应该建立一棵最小生成树,然后修复树中所有的边即可。

然后国家帮忙修复边权<=p的部分,那么我们可以想到,当p较大时,牛牛的资金肯定可以足够修复剩下的,当p较小时,牛牛要修的路就比较多,就修不了。

所以“y=牛牛能否修复剩下的路”是随着p单调的,当p大时,y=1,当p小时,y=0,我们要做的就是找到那个交界处,二分即可。

#include <bits/stdc++.h>
#define int long long
using namespace std;
const int maxn = 1e5 + 9;

map<int, int> mp[maxn];

struct Edge
{
    int x, y, w;
};

int pre[maxn];
//路径压缩的并查集
int root(int x){return pre[x] = (pre[x] == x ? x : root(pre[x]));}

int a[maxn];//a里面存放最小生成树的所有边权
int n, m, c, cnt;

bool check(int k)
{
    int res = 0;//贪心求最小代价,数组逆序点乘
    for(int i = cnt, j = 0;i >= 1; -- i)
    {
        if(a[i] <= k)break;//<=k的部分国家买单不用考虑了
        res += (++ j) * a[i];
    }
    return res <= c;
}

signed main()
{
    scanf("%lld %lld %lld", &n, &m, &c);
    /*最小生成树,共3步*/
    vector<Edge> vec;
    //1.存边
    for(int i = 1;i <= m; ++ i)
    {
        int x, y, w;scanf("%lld %lld %lld", &x, &y, &w);
        vec.push_back({x, y, w});//将边存入vec中
    }
    //2.将边升序
    sort(vec.begin(), vec.end(), [](const Edge &u, const Edge &v)
         {
             return u.w < v.w;
         });
    //3.贪心建树,并查集判断连通性
    for(int i = 1;i <= n; ++ i)pre[i] = i;//并查集初始化
    for(auto &i : vec)
    {
        int x = i.x, y = i.y, w = i.w;
        if(root(x) == root(y))continue;
        a[++ cnt] = w;//a自然是升序的
        pre[root(x)] = root(y);
    }
    
    /*生成树结束*/
    
    //以下为二分部分
    int l = -1, r = 2e9;
    
    while(l + 1 != r)
    {
        int mid = (l + r) >> 1;
        if(check(mid))r = mid;
        else l = mid;
    }
    printf("%lld\n", r);
    return 0;
}

E-等腰三角形(easy)

暴力枚举。

枚举出所有三个点组成的三元组,注意不要重复。

可以通过海伦公式来求面积判断是否共线。

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

const int maxn = 500;
const double eps = 1e-6;

struct Point
{
    int x, y;
}p[maxn];

int dist(const Point &u, const Point &v)
{
    int dx = u.x - v.x;
    int dy = u.y - v.y;
    return dx * dx + dy * dy;
}

double area(double a, double b, double c)
{
    double p = (a + b + c) / 2.0;
    return sqrt(p * (p - a) * (p - b) * (p - c));
}

signed main()
{
    int n;scanf("%lld", &n);
    for(int i = 1;i <= n; ++ i)
        scanf("%lld %lld", &p[i].x, &p[i].y);
    int ans = 0;
    for(int i = 1;i <= n; ++ i)
    {
        for(int j = i + 1;j <= n; ++ j)
        {
            for(int k = j + 1;k <= n; ++ k)
            {
                int d1 = dist(p[i], p[j]);
                int d2 = dist(p[i], p[k]);
                int d3 = dist(p[j], p[k]);
                if(area(sqrt(d1), sqrt(d2), sqrt(d3)) <= eps)continue;
                if(d1 == d2 || d1 == d3 || d2 == d3)ans ++;
            }
        }
    }
    printf("%lld\n", ans);
    return 0;
}

F-等腰三角形(hard)

这题肯定不能暴力枚举了。

我们可以发现,以整数点作为定点肯定无法构成等边三角形。

假如我们要构成一个等边三角形,那么就需要有60度的角,假如这个60度的角由两个角x,y相加而成,就有:

$$ tan60\degree = tan(x+y)= \frac{tanx + tany}{1-tanx \times tany}$$

其中tan60是一个无理数,但是后面的tanx, tany都是有理数,一个无理数无法通过有理数的加减乘除算出,所以在整数点中构造不出60度的角。

我们枚举每一个点A,然后枚举其他点作为B,然后再查一下有多少C即可(也就是和A距离等于dist(AB)的点),这里只需保证C的下标小于B的下标,就保证了一个偏序关系,就不会重复计算。

接下来需要将“三点共线”的这样“特殊等腰三角形”减去,我们只需计算有多少这样的“线段”即可。

枚举每一个点A,再查一下A'是否存在即可,可以对点做一个桶来判断,因为地图并不大。

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

const int maxn = 3009, T = 1000;
const double eps = 1e-6;

struct Point
{
    int x, y;
}p[maxn];

int dist(const Point &u, const Point &v)
{
    int dx = u.x - v.x;
    int dy = u.y - v.y;
    return dx * dx + dy * dy;
}

int cnt[2123456];
bitset<2005> vis[2005];

signed main()
{
    int n;scanf("%lld", &n);
    for(int i = 1;i <= n; ++ i)
    {
        scanf("%lld %lld", &p[i].x, &p[i].y);
        vis[p[i].x + T][p[i].y + T] = true;
    }
    
    
    int ans = 0;
    for(int i = 1;i <= n; ++ i)
    {
        for(int j = 1;j <= n; ++ j)
        {
            if(i == j)continue;
            
            ans += (cnt[dist(p[i], p[j])] ++);
        }
        for(int j = 1;j <= n; ++ j)
        {
            if(i == j)continue;
            
            cnt[dist(p[i], p[j])] = 0;
        }
    }
    int cnt = 0;
    for(int i = 1;i <= n; ++ i)
    {
        for(int j = 1;j <= n; ++ j)
        {
            if(i == j)continue;
            int tx = 2 * p[j].x - p[i].x;
            int ty = 2 * p[j].y - p[i].y;
            if(tx < -500 || tx > 500 || ty < -500 || ty > 500)continue;
            
            if(vis[tx + T][ty + T])cnt ++;
        }
    }
    printf("%lld\n", ans - cnt / 2);
    return 0;
}

? 本文由eriktse原创,创作不易,如果对您有帮助,欢迎小伙伴们点赞?、收藏⭐、留言?

有关【牛客小白月赛69】题解与分析A-F【蛋挞】【玩具】【开题顺序】【旅游】【等腰三角形(easy)】【等腰三角形(hard)】的更多相关文章

  1. 【算法题解】20. 两数之和 - 2

    这是一道简单题题目来自:https://leetcode.cn/problems/two-sum/题目给定一个整数数组nums和一个整数目标值target,请你在该数组中找出和为目标值target的那两个整数,并返回它们的数组下标。你可以假设每种输入只会对应一个答案。但是,数组中同一个元素在答案里不能重复出现。你可以按任意顺序返回答案。提示:22nums.length104−109−109nums[i]109−109−109target109只会存在一个有效答案进阶:你可以想出一个时间复杂度小于O(n2)O(n^2)O(n2)的算法吗?示例1:输入:nums=[2,7,11,15],targe

  2. ARM异常处理(3):Bus faults、Memory management faults、Usage faults、Hard faults详解 - 2

    之前介绍了了ARM异常处理(1):异常类型、优先级分组和异常向量表,里面有很多异常类型,其中有几个异常在错误处理中非常有用:文章目录1BusFault2MemoryManagementFault3Uagefaults4HardFaults1BusFault当在AHB接口上传输期间收到错误响应时,就会产生Busfault。它可能发生在以下几个阶段:指令预取阶段,通常称为prefetchabort数据读/写阶段,通常称为dataabort在Cortex-M3中,出现下面几种情况也会产生Busfault:堆栈在中断处理的开始处PUSH,称为stackingerror堆栈在中断处理的结束处POP,称为

  3. [青少年CTF] easy_web 详解+避坑 - 2

     首先打开环境 查看源码发现有个base64解开后发现是图片源码这让我联想到地址栏中的参数  发现它经过了两次base64编码和一次十六进制编码Base64在线编码解码|Base64加密解密-Base64.usCTF在线工具-Hex在线编码|Hex在线解码|十六进制编码转换(hiencode.com) 解开后发现是图片名 我们反向操作一波查看index.php的源码 696e6465782e706870TmprMlpUWTBOalUzT0RKbE56QTJPRGN3下面传参 进行base64解密  得到源码';die("xixi~noflag");}else{$txt=base64_encod

  4. 若依整合Easy-Es实现文章列表分页查询 - 2

    Easy-Es(简称EE)是一款基于ElasticSearch(简称Es)官方提供的RestHighLevelClient打造的ORM开发框架,在RestHighLevelClient的基础上,只做增强不做改变,为简化开发、提高效率而生,您如果有用过Mybatis-Plus(简称MP),那么您基本可以零学习成本直接上手EE,EE是MP的Es平替版,在有些方面甚至比MP更简单,同时也融入了更多Es独有的功能,助力您快速实现各种场景的开发。目录1、ES的优点2、整合过程(1)配置文件(2

  5. ARM6818开发板画任意矩形,圆形,三角形,五角星,6818开发板画太极,画五星红旗(含码源与思路) - 2

    本文利用6818开发板完成LCD屏上绘制任意的矩形,圆形,三角形或五角星形图案,还有绘制太极,五星红旗的方案。 目录映射绘制矩形代码思路代码实现 实践出真知绘制圆形代码思路代码实现绘制三角形代码思路代码实现绘制五角星代码思路代码实现绘制太极代码思路代码实现绘制五星红旗代码思路代码实现映射#include#include#include#include#include#include#include#includeunsignedint*plcd=NULL;/*Lcd_Init:LCD初始化,打开LCD屏幕,并完成映射机制*/intLcd_Init(){ intfd=open("/dev/fb0

  6. javascript - 检测 Node.js 中的硬链接(hard link) - 2

    如何判断文件系统路径是否是Node.js的硬链接(hardlink)?函数fs.lstat给出了一个stats对象,当给定硬链接(hardlink)时,该对象将为stats.isDirectory()和返回truestats.isFile()分别。fs.lstat没有提供任何东西来说明普通file或directory与链接文件之间的区别。如果我对链接(ln)工作原理的理解是正确的,那么链接文件指向磁盘上与原始文件相同的位置。这意味着原始文件和链接版本是相同的,并且无法区分原始文件和链接文件。我正在寻找的功能如下:Thisishypotheticalpseudo-codefordemon

  7. 蓝桥杯第十四届省赛完整题解 C/C++ B组 - 2

    没有测评,不知道对不对,仅仅过样例而已试题A:日期统计本题总分:5分【问题描述】小蓝现在有一个长度为100的数组,数组中的每个元素的值都在0到9的范围之内。数组中的元素从左至右如下所示:5686916124919823647759503875815861830379270588570991944686338516346707827689565614010094809128502533现在他想要从这个数组中寻找一些满足以下条件的子序列:   1.子序列的长度为8;   2.这个子序列可以按照下标顺序组成一个yyyymmdd格式的日期,并且要求这个日期是2023年中的某一天的日期,例如202309

  8. 2023第十四届蓝桥杯C/C++B组省赛题解 - 2

    2023蓝桥C/C++B组省赛文章目录2023蓝桥C/C++B组省赛试题A:日期统计题目描述枚举参考代码试题B:01串的熵题目描述枚举|模拟参考代码试题C:冶炼金属题意描述取交集参考代码试题D:飞机降落题意描述DFS+剪枝,懒得写试题E:接龙数列题意描述DP参考代码试题F:岛屿个数题意描述dfs|连通块参考代码试题G:子串简写题意描述前缀和参考代码试题H:整数删除题意描述双向链表|最小堆参考代码试题I:景区导游题意描述带权LCA参考代码试题J:砍树题意描述树上差分参考代码试题A:日期统计题目描述【问题描述】小蓝现在有一个长度为100的数组,数组中的每个元素的值都在0到9的范围之内。数组中的元素

  9. opengl - 为什么这个 OpenGL 程序不绘制三角形? - 2

    我正在尝试学习现代OpenGL并想像这样绘制一个三角形:我正在学习本教程:www.opengl-tutorial.org/beginners-tutorials/tutorial-2-the-first-triangle/,但我得到的只是深蓝色背景(清晰的颜色)。这段代码可能有什么问题?我正在用Go编写此代码并尝试在Ubuntu和OSX上运行它。注意:我使用的是glfw3库,而不是教程中使用的glfw2.7。我认为相关的部分是:funcsetup(){gl.ClearColor(0.0,0.0,0.4,0.0)makeProgram(vertexShaderSource,fragmen

  10. 【攻防世界】Web very_easy_sql - 2

    做了web才发现,原来自己是真的什么都不懂啊,不过也好,说明我有很大的进步空间呢······不闲聊了,来看题目打开是一个登录界面,我们抓包看看返回些什么返回包有三个需要注意的地方,我都用框框圈起来了有一个Set-Cookie代表如果输入正确的账号跟密码是可以返回的,可以尝试爆破第二个发现了一个新的页面use.php,我们可以访问看看第三个,返回了一句话:youarenotaninneruser,sowecannotletyouhaveidentify~翻译就是:您不是内部用户,所以我们不能让您有身份~意思应该是我们要从内部登录吧?我们访问一下use.php这个页面看起来是一个输入url能跳转的

随机推荐