每日一题:view outlook(简单练习题)

这篇博客探讨了一个问题,即在一组等距的建筑物中,如何找到一座可以看到最多其他建筑物楼顶的楼。根据题目描述,从某座楼上看其他楼,当连接两楼的线段不与其他线段接触或相交时,即可看到。博主提出了两种思路,一种是从左到右考虑斜率递减,另一种是从右到左考虑斜率递增。通过遍历所有楼并计算能看到的其他楼数量,找到能看到最多楼的那座。最终给出的代码实现了这一算法,输出了能看到最多楼的数量和该楼的编号。

/*
描述:view outlook
假设有一些距离相同的楼,求第个楼楼顶能看到最多其他楼顶的风光
从第 i 座大楼能看到第 j 座大楼当且仅当连接这两个楼顶的线段不与任何其他高楼对应的线段接触或相交。
示例:例如它们的高度是2 3 1 2 3
注意这里的输入是5 2 3 1 2 3 别搞错了
则输出4 2:意思是从第二座楼上可以看见所有其他的楼
*/
/ * 思路:从第i个楼,左边的斜率递减,右边的斜率递增 */

这里的思路跟我们平时想的时候差不多,处于某一座楼上我们从低到高来看,转化成斜率就是得分左右两边斜率需要符合条件。左右两边都是一个高度递增序列(其实我觉得这个思路也行,下面这个思路是题解中的,明天写写。。)

/*描述:view outlook 
假设有一些距离相同的楼,求第个楼楼顶能看到最多其他楼顶的风光
从第 i 座大楼能看到第 j 座大楼当且仅当连接这两个楼顶的线段不与任何其他高楼对应的线段接触或相交。
示例:例如它们的高度是2 3 1 2 3
注意这里的输入是5 2 3 1 2 3 别搞错了 
则输出4 2 
*/
/*思路:从第i个楼,左边的斜率递减,右边的斜率递增*/ 
#include<bits/stdc++.h>
using namespace std;

int main() {
    int n;
    cin >> n;
    //n个整型元素的向量,初值都为0 
    vector<int> a(n, 0);
    //输入每个楼个高度 
    for (int i = 0; i < n; i++) {
        cin >> a[i];
    }
    //存储最大个数 
    int res = 0;
    //存储第几座
	int flag = 0; 
    //从1到n座楼开始遍历,找出看到最多风景的楼 
    for (int i = 0; i < n; i++) {
    	//存储每个楼能观看其他楼的个数 
        int ress = 0;
        int l = i - 1;
        double ll1 = 100000000000000;//这个是测试数据
        //遍历左边的楼,从i-1到0斜率递减
        while (l >= 0) {
        	//求斜率
            double kk = double((a[i] - a[l])) / double((i - l));
            if (kk < ll1) {
                ll1 = kk;
                ress++; //如果符合递减的条件则加1 
            }
            l--;
        }
        int r = i + 1;
        double rr1 = 100000000000000;
        //遍历右边的楼,从i+1到n斜率递增
        while (r <= n-1) {
        //处理一下斜率使它递减,方便统一
            double kk = double((a[i] - a[r])) / double((r - i));
            if (kk < rr1) {
                rr1 = kk;
                ress++;	//如果符合递减条件则总数加1 
            }
            r++;
        }
		//每次遍历后比较存储最大的 
		if(ress > res){
        	flag = i + 1;
		}
        res = max(res, ress);
    }
    cout << res << " ";
    cout << flag;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值