POJ-2726-Holiday Hotel
| Time Limit: 2000MS | Memory Limit: 65536K | |
| Total Submissions: 8302 | Accepted: 3249 |
Description
- Any hotel which is closer to the seashore than M will be more expensive than M.
- Any hotel which is cheaper than M will be farther away from the seashore than M.
Input
Output
Sample Input
Sample Output
-------------------------------------------------
分析:这道题折腾了我一晚上也没AC,直到第二天早上起来才恍然大悟,心里暗骂出题人100遍,网上有人说貌似是楼教主出的,好吧我承认一开始我对题的理解有问题。首先,这道题的模型很简单,即任何比M旅店离海边近的旅店都比M酒店要贵,至于第二个条件,其实就是第一个条件的逆否命题,用来迷惑你的,嘿嘿!现在的关键是我们如何理解这个条件并把它转化为数学语言,你可能二话不说直接写出了这个数学形式的逻辑语句:∀i,if Di<DM ⇒ Ci>CM ,能写出来这个,证明你高一数学学的很好,跟我一样好。但是我们都犯了一个错误,那就是没有结合题意去讨论特殊情形。首先,我们看一下样例输入,发现有两个旅店距离海边都为100,它们同是离海边最近的旅店,但是它们的价格是不一样的,Smith夫妇选旅店会把它们两个同时作为候选项吗?显然不会!距离相同时,它们当然只会把更便宜的作为候选项,贵的那个直接抛弃!而对于我们之前写的表达式,显然它们两个是都满足的,原因是我们并没有考虑到距离相同时的情形,当然如果出题人好心的话也应该指出这种情况。修改后的逻辑语句:∀i,if Di≤DM ⇒ Ci>CM
接下来的思路就明朗了,我们依据离海边的距离对所有旅店进行排序,这里我们使用的是修改后的快速排序(即对D进行排序,C跟随,当然把旅店定义成结构体或类更方便),当两个酒店离海边距离相同时,我们把便宜的那个排在前面,然后我们就可以把D看成自变量x,C看成因变量y,初始时就已经有一个满足条件的旅店M(因为没有比排在最前面的那个旅店离海边更近并且还更便宜的了),即初始时candidate_n = 1,我们从第二个旅店向后扫描C,每找到一个CM比之前的C都小,计数器candidate_n就加1,最后输出candidate_n即可。
源码:
#include<iostream>
using namespace std; void exchange(int A[], int i, int j) // 交换A[i]和A[j]
{
int temp = A[i];
A[i] = A[j];
A[j] = temp;
} int partition(int A[], int B[], int left, int right)// 划分函数
{
int pivot_A = A[right]; // 选择子数组最后一个元素作为基准
int pivot_B = B[right];
int tail = left - ; // tail为小于基准的子数组最后一个元素的索引
for (int i = left; i < right; i++) // 遍历基准以外的其他元素
{
if (A[i] < pivot_A) // 把小于基准的元素放到前一个子数组中
{
tail++;
exchange(A, tail, i);
exchange(B, tail, i);
}
if (A[i] == pivot_A && B[i] < pivot_B) // 当两个酒店离海边距离相同时,我们把便宜的那个排在前面
{
tail++;
exchange(A, tail, i);
exchange(B, tail, i);
}
}
exchange(A, tail + , right); // 最后把基准放到前一个子数组的后边,剩下的子数组既是大于基准的子数组
exchange(B, tail + , right);
return tail + ; // 返回基准的索引
} void quicksort(int A[], int B[], int left, int right)
{
int pivot_index = A[right];
if (left < right)
{
pivot_index = partition(A, B, left, right);
quicksort(A, B, left, pivot_index - );
quicksort(A, B, pivot_index + , right);
}
} int main()
{
int N,candidate_n = ;
while (scanf("%d", &N) && N) // 输入酒店的个数N,N为0时直接结束程序
{
int* D = (int *)malloc(N * sizeof(int));// 为了节省空间这里我们根据N的大小动态分配内存
int* C = (int *)malloc(N * sizeof(int));
for (int i = ; i < N; i++)
{
scanf("%d%d", &D[i], &C[i]);
}
quicksort(D, C, , N - ); // 调用修改后的快排算法依据D对旅店进行排序,C跟随
int min = C[];
candidate_n = ; // 排在最前面的旅店必然满足条件
for (int i = ; i < N; i++)
{
if (C[i] < min) // 每找到一个旅店比前面的都便宜
{
min = C[i];
candidate_n++; // 计数器加1
}
}
printf("%d\n", candidate_n);
candidate_n = ;
free(D); // 释放空间
free(C);
}
return ;
}
显然,程序的时间复杂度O(nlogn),运行结果如下:

POJ-2726-Holiday Hotel的更多相关文章
- POJ 题目3667 Hotel(线段树,区间更新查询,求连续区间)
Hotel Time Limit: 3000MS Memory Limit: 65536K Total Submissions: 13805 Accepted: 5996 Descriptio ...
- POJ 3667 & 1823 Hotel (线段树区间合并)
两个题目都是用同一个模板,询问最长的连续未覆盖的区间 . lazy代表是否有人,msum代表区间内最大的连续长度,lsum是从左结点往右的连续长度,rsum是从右结点往左的连续长度. 区间合并很恶心啊 ...
- POJ 2726
#include <iostream> #include <algorithm> #define MAXN 10005 using namespace std; struct ...
- A过的题目
1.TreeMap和TreeSet类:A - Language of FatMouse ZOJ1109B - For Fans of Statistics URAL 1613 C - Hardwood ...
- 线段树(区间合并) POJ 3667 Hotel
题目传送门 /* 题意:输入 1 a:询问是不是有连续长度为a的空房间,有的话住进最左边 输入 2 a b:将[a,a+b-1]的房间清空 线段树(区间合并):lsum[]统计从左端点起最长连续空房间 ...
- poj 3667 Hotel (线段树)
http://poj.org/problem?id=3667 Hotel Time Limit: 3000MS Memory Limit: 65536K Total Submissions: 94 ...
- POJ P3667 Hotel——solution
Description The cows are journeying north to Thunder Bay in Canada to gain cultural enrichment and e ...
- POJ 3667 Hotel(线段树)
POJ 3667 Hotel 题目链接 题意:有n个房间,如今有两个操作 1.找到连续长度a的空房间.入住,要尽量靠左边,假设有输出最左边的房间标号,假设没有输出0 2.清空[a, a + b - 1 ...
- 整理下线段树吧 poj hotel
除了上次的新学的有 区间更新 延迟更新 区间合并 先说下区间更新以及延迟更新吧 既然是对区间的维护 在求解一些问题的时候 有的时候没有必要对所有的自区间都进行遍历 这个时候 延迟标记就派上用场了 ( ...
随机推荐
- Setup Factory Error3014
在用Setup Factory打包软件的时候出现Error3014 一般都是由于软件冲突引起的 我的问题是由于杀毒软件 ,在打包的时候关闭杀毒软件 就能成功打包了.
- update
update `表名` set 字段名 =replace(字段名, '查找的内容','更改的内容') where 字段名 like '%查找的内容%'; update shangpin set cli ...
- javascript new
1. 仅function可以使用new 2. function使用new时,会拷贝function中this的内容给新对象,并将function的prototype指向新对象(如果该function没 ...
- WCF初探-19:WCF消息协定
WCF消息协定概述 在生成 WCF应用程序时,开发人员通常会密切关注数据结构和序列化问题,而不必关心携带数据的消息结构. 对于这些应用程序,为参数或返回值创建数据协定的过程很简单.但是,有时完全控制 ...
- hdu 4747 Mex
http://acm.hdu.edu.cn/showproblem.php?pid=4747 设我们输入的数组为 a[],我们需要从 1 到 n 遍历, 假设遍历到 i 时, 遍历的过程中用b[j]表 ...
- 苹果5S指纹扫描识别传感器Touch ID有利于iPhone的安全性
iPhone5S新增的指纹扫描识别传感器 Touch ID,黑客花了大量的时间表明指纹验证是可以被破解的.即使它可能被黑客攻击,对iPhone5S的安全性而言,仍然具有极大的好处. 为什么一个容易被破 ...
- ajax对象属性withCredentials
默认情况下,ajax跨源请求不提供凭据(cookie.HTTP认证及客户端SSL证明等).通过将设置ajax的withCredentials属性设置为true,可以指定某个请求应该发送凭据.如果服务器 ...
- Objective-C学习笔记-第二天(1)
Objective-C中,调用方法采用的是一种消息传递机制. 参考文章:http://blog.csdn.net/xingyevc/article/details/39397873 如果向某个对象传递 ...
- Gradle for Android
1.project vs project.rootProject 2.System.console() != null ? System.console().readPassword("\n ...
- Linux kernel map