2015百度之星初赛(1)题解(1001)

本文解析了两道经典的算法题目,第一题为简单的贪心算法题,通过排序和逐步增加攻击力来判断胜负;第二题涉及计算几何,使用格雷厄姆扫描算法求解凸包并计算最小矩形覆盖面积。

1001:  简单的贪心题。首先我们特判必赢和必输的两种状态(max<m,min>m),然后对战斗力排序,找到在0~m之间最大的战斗力作为初始值,

然后,每一次将攻击力提升至 下一个彪形大汉的值,同时k--,如果一旦发现打不过,那么必输,break。注意战斗力1e12,用__int64

#include<iostream>
#include<cstdio>
#include<string>
#include<cstring>
#include<algorithm>
using namespace std;
__int64 s[10005];
int main()
{
	__int64 T, n, m, k;
	scanf("%I64D", &T);
	__int64 cas = 1;
	while (T--)
	{
		scanf("%I64D%I64D%I64D", &n,&m,&k);
		for (__int64 i = 1; i <= n; i++)
			scanf("%I64D", &s[i]);
		sort(s + 1, s + n + 1);
		cout << "Case #" << cas++ << ":" << endl;
		if (s[n] <= m)
		printf("why am I so diao?\n");
		else if (s[1] > m)
		printf("madan!\n");
		else
		{
			__int64 ind = 0;
			for (__int64 i = 1; i <= n; i++)
			{
				if (s[i] >= 0 && s[i] <= m)
					ind = i;
			}
			__int64 attack = s[ind];
		   int flag = 1;
		   for (__int64 i = ind; i <= n; i++)
			{
				if (attack < s[i])
				{
					flag = 0;
					break;
				}
				else if (attack == s[i])
				{
					if (i + 1 <= n&&attack + k >= s[i + 1])
					{
						attack = attack + s[i + 1] - s[i];
						k--;
						k = max(k, (__int64)0);
					}
				}
				
			}
			if (flag)
				printf("why am I so diao?\n");
			else
				printf("madan!\n");
		}
	}
	return 0;
}
1006 :

最小矩形覆盖,模板题。注意结果是四舍五入。

#include<stdio.h>
#include<iostream>
#include<string.h>
#include<cstring>
#include<algorithm>
#include<math.h>
using namespace std;
#define PR 1e-8
#define N 4010
#define maxdouble 1e20
int T, n, ans;
struct TPoint
{
    double x, y;
};
struct TPolygon
{
    int n;
    TPoint p[N];
}ply;
double MIN(double a, double b) { return a>b ? b : a; }
int dblcmp(double a)
{
    if (fabs(a)<PR) return 0;
    return a>0 ? 1 : -1;
}
double dist(TPoint a, TPoint b)//距离
{
    double s1 = a.x - b.x;
    double t1 = a.y - b.y;
    return sqrt(s1*s1 + t1*t1);
}
double cross(TPoint a, TPoint b, TPoint c)//叉积
{
    double s1 = b.x - a.x;
    double t1 = b.y - a.y;
    double s2 = c.x - a.x;
    double t2 = c.y - a.y;
    return s1*t2 - s2*t1;
}
double dot(TPoint a, TPoint b, TPoint c)//点积
{
    double s1 = b.x - a.x;
    double t1 = b.y - a.y;
    double s2 = c.x - a.x;
    double t2 = c.y - a.y;
    return s1*s2 + t1*t2;
}
bool cmop(TPoint a, TPoint b)//x、y排序
{
    if (fabs(a.x - b.x)<PR) return a.y<b.y;
    else return a.x<b.x;
}
bool cmp(TPoint a, TPoint b)//叉积内排序
{
    int d1 = dblcmp(cross(ply.p[0], a, b));
    return d1>0 || (d1 == 0 && dist(ply.p[0], a)<dist(ply.p[0], b));
}
TPolygon graham()//求凸包
{
    int i, top = 2;
    for (i = 2; i<ply.n; i++)
    {
        while (top>1 && (dblcmp(cross(ply.p[top - 2], ply.p[i], ply.p[top - 1]))) >= 0) top--;
        ply.p[top++] = ply.p[i];
    }
    ply.n = top;
    return ply;
}
double solve()
{
    int i, p = 1, q = 1, r;
    double minarea = maxdouble, area;
    ply.p[ply.n] = ply.p[0];
    for (i = 0; i<ply.n; i++)
    {
        while (dblcmp(cross(ply.p[i], ply.p[i + 1], ply.p[p + 1])//最上一点
            - cross(ply.p[i], ply.p[i + 1], ply.p[p]))>0)
            p = (p + 1) % ply.n;
        while (dblcmp(dot(ply.p[i], ply.p[i + 1], ply.p[q + 1])//最右一点
            - dot(ply.p[i], ply.p[i + 1], ply.p[q]))>0)
            q = (q + 1) % ply.n;
        if (i == 0) r = q;
        while (dblcmp(dot(ply.p[i], ply.p[i + 1], ply.p[r + 1])//最左一点
            - dot(ply.p[i], ply.p[i + 1], ply.p[r])) <= 0)
            r = (r + 1) % ply.n;
        double d = dist(ply.p[i], ply.p[i + 1])*dist(ply.p[i], ply.p[i + 1]);
        area = cross(ply.p[i], ply.p[i + 1], ply.p[p])*
            (dot(ply.p[i], ply.p[i + 1], ply.p[q]) - dot(ply.p[i], ply.p[i + 1], ply.p[r])) / d;
        minarea = MIN(area, minarea);//更新
    }
    return minarea;
}
int main()
{
    scanf("%d", &T);
    //while (scanf("%d", &ply.n), ply.n)
    for (int Case = 1; Case <= T; ++Case)
    {
        scanf("%d", &n);
        ply.n = 4 * n;
        int i;
        double area;
        for (i = 0; i<ply.n; i++) scanf("%lf%lf", &ply.p[i].x, &ply.p[i].y);
        sort(ply.p, ply.p + ply.n, cmop);//排序
        sort(ply.p + 1, ply.p + ply.n, cmp);
        ply = graham();//凸包
        if (ply.n<3) area = 0;
        else area = solve();
        printf("Case #%d:\n", Case);
        ans = area + 0.5;
        printf("%d\n", ans);
    }
    return 0;
}



### 关于2024百度初赛第一场的题目解析 目前尚未有官方发布的关于2024百度初赛第一场的具体题目解析文档被广泛传播或公开引用。然而,基于以往的比赛惯例以及社区讨论的内容[^1],可以推测该比赛通常涉及算法设计、数据结构应用以及编程技巧等方面的知识。 #### 题目类型分析 根据过往几百度竞赛的特点,其题目可能涵盖但不限于以下几个方面: - **字符串处理**:此类问题经常考察参赛者对于复杂模式匹配的理解能力,例如KMP算法的应用场景或者正则表达式的高效实现方法。 - **动态规划 (Dynamic Programming)**:这是解决最优化问题的一种重要手段,在许多比赛中都会出现。它通过把原问题分解成相对简单的子问题来求解复杂问题的方法[^2]。 - **图论(Graph Theory)**:包括但不限于最小生成树(MST),单源最短路径(SSSP)等问题都是常见考点之一。这些都需要扎实的基础理论支持才能快速找到最优解答方案[^3]。 以下是针对假设性的几类典型问题提供一些通用思路和技术要点说明: --- #### 字符串处理案例解析 如果遇到需要频繁查询某个特定字符序列是否存在的情况,则可考虑构建AC自动机来进行批量检索操作;而对于仅需判断两个字符串之间关系的任务来说,双指针技术往往能够满足需求并保持较低时间复杂度O(n)[^4]。 ```python def is_subsequence(s, t): it = iter(t) return all(char in it for char in s) # Example Usage: print(is_subsequence("abc", "ahbgdc")) # Output: True ``` --- #### 动态规划实例讲解 当面临背包问题变种或是区间覆盖等相关挑战时,定义状态转移方程至关重要。比如经典的一维数组形式dp[i]=max(dp[i], dp[j]+w(i,j))表示从前j项选取若干物品放入容量不超过i的情况下所能获得的最大价值总和[^5]。 ```python def knapsack(weights, values, capacity): n = len(values) dp = [0]*(capacity+1) for i in range(1,n+1): w,v=weights[i-1],values[i-1] for j in reversed(range(capacity+1)): if j >=w : dp[j]= max(dp[j], dp[j-w]+v ) return dp[-1] # Example Usage: weights=[2,3,4] values =[3,4,5] capacity=5 result=knapsack(weights,values,capacity) print(result) # Output:7 ``` --- #### 图论基础概念复习 在面对连通性验证或者是寻找关键节点这样的任务时,BFS/DFS遍历配合并查集Union-Find的数据结构通常是首选策略。它们能够在几乎线性时间内完成大规模网络拓扑属性计算工作[^6]。 ```python from collections import defaultdict, deque class Graph: def __init__(self): self.graph = defaultdict(list) def addEdge(self,u,v): self.graph[u].append(v) self.graph[v].append(u) def BFS(self,start_vertex): visited=set() queue=deque([start_vertex]) while(queue): vertex=queue.popleft() if(vertex not in visited): visited.add(vertex) queue.extend(set(self.graph[vertex])-visited) return list(visited) g=Graph() edges=[[0,1],[0,2],[1,2],[2,3]] for u,v in edges:g.addEdge(u,v) res=g.BFS(2) print(res) #[2, 0, 1, 3] ``` 尽管以上只是部分可能涉及到的技术领域概述及其简单示例展示,但对于准备参加类似赛事的学习者而言已经具备相当指导意义了。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值