hudu 1050 sort oj上的易错点 贪心算法

本文介绍了一个简单的任务调度问题,并使用贪心算法进行求解。通过对比不同返回类型的比较函数,阐述了如何使代码适配在线评测系统(OJ)。文章详细展示了算法实现过程及关键代码。

很容易的一道题,用的贪心算法。

开始sort中的comp函数返回int,在本地运行时无论怎么测试都是对的,就是过不了OJ。

int comp(ss a,ss b)
{
	return a.s < b.s;
}

原来OJ上只能让comp返回bool才能过

#include<stdio.h>
#include<math.h>
#include<stdlib.h>
#include<string.h>
#include<algorithm> 
using namespace std;

typedef struct ss
{
	int s,e; 
}ss;
ss __[205];
int vis[205];
bool comp(ss a,ss b)
{
	return a.s < b.s;
}
int main()
{	
	int t,n,temp1,temp2,i,count,num,last;
	scanf("%d",&t);
	while(t--)
	{
		memset(vis,0,sizeof(vis));
		scanf("%d",&n);
		for(i = 0; i < n; i++)
		{
			scanf("%d%d",&temp1,&temp2); 
			__[i].s = temp1 < temp2?(temp1 + 1)/2:(temp2 + 1)/2;
			
			__[i].e = temp1 > temp2?(temp1 + 1)/2:(temp2 + 1)/2;
		}
		sort(__,__+n,comp);
		num = 0;count = 0; 
		while(num != n)
		{
			last = 0;
			for(i = 0; i < n; i++)
			{
				if(vis[i] == 0 && __[i].s > last)
				{
					last = __[i].e;
					vis[i] = 1;
					num++;
				}
			}
			count++;
			
		}
		printf("%d\n",count * 10);
	}
	return 0;
} 


```markdown ### 代码概述 你的代码逻辑已经很接近正确了,但仍有 **两个致命错误** 导致结果不对: 1. ❌ `f / 60` 和 `s / 3600` 是整数除法(会截断) 2. ❌ 输入格式中的 `\n` 可能导致程序“卡住”或读错数据 我们来逐行解析并修复。 --- ### 代码解析 #### 🔴 错误1:整数除法导致精度丢失 ```c double jiaodu = d + f / 60 + s / 3600; ``` ⚠️ 问题出在: - `f` 是 `int` 类型,`60` 是整数 → `f / 60` 是整数除法! - 比如 `f = 48`,那么 `48 / 60 = 0`(不是 `0.8`)! - 同理,`s / 3600` 如果 `s` 是小数但除以整数,也可能被截断 ✅ 必须改成: ```c double jiaodu = d + f / 60.0 + s / 3600.0; ``` 👉 使用 `60.0` 和 `3600.0` 强制转为浮除法! --- #### 🔴 错误2:输入格式中 `\n` 多余且危险 ```c scanf("%lf %lf\n%d %d %lf", &a, &b, &d, &f, &s); ↑↑↑ ``` `\n` 在 `scanf` 中的含义是“跳过任意空白字符”,但它会一直等待直到遇到非空白字符。 这可能导致程序**卡住不继续运行**,特别是在标准输入换行时! ✅ 正确写法: ```c scanf("%lf %lf %d %d %lf", &a, &b, &d, &f, &s); ``` 空格自动跳过换行和空格,安全可靠。 --- #### ✅ 其他部分基本正确: - `hudu = jiaodu * 3.141592653589793 / 180.0;` → 正确转换为弧度 - `tan(hudu)` → 正确使用弧度制 - `printf("%.2f\n", h);` → 输出两位小数,四舍五入 --- ### ✅ 修复后的正确代码 ```c #include <stdio.h> #include <math.h> int main() { double a, b, s; int d, f; // 修复1:去掉 \n,避免卡住 scanf("%lf %lf %d %d %lf", &a, &b, &d, &f, &s); // 修复2:用 60.0 和 3600.0 避免除法截断 double jiaodu = d + f / 60.0 + s / 3600.0; // 角度转弧度(正确) double hudu = jiaodu * 3.141592653589793 / 180.0; // 计算烟囱高度 double h = a * tan(hudu) + b; // 输出保留两位小数 printf("%.2f\n", h); return 0; } ``` --- ### 🧪 测试样例验证 输入: ``` 27.8 1.2 32 48 59.5 ``` 计算过程: - `jiaodu = 32 + 48/60.0 + 59.5/3600.0 = 32 + 0.8 + 0.016527778 = 32.816527778°` - `hudu = 32.816527778 * π / 180 ≈ 0.572794 rad` - `tan(hudu) ≈ 0.6471` - `h = 27.8 * 0.6471 + 1.2 ≈ 17.93 + 1.2 = 19.13` 输出: ``` 19.13 ``` ✅ 完全正确! --- ### 知识 - **整数除法会截断结果**:`48/60` 得 0,必须写成 `48/60.0` 才能得到 0.8。 - **`scanf` 中不要滥用 `\n`**:`\n` 会导致输入阻塞,应使用空格自动跳过空白。 - **角度必须转弧度才能用 `tan`**:公式为 $ \text{弧度} = \text{角度} \times \pi / 180 $,且 $ \pi $ 建议取高精度值。 ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值