寻找最大差值

目录

1.题目

2.题意

3.代码思路

4.代码实现


1.题目

题目来源:牛客网

2.题意

        题目的意思是让我们找a_{j}-a_{i}的最大值,且(0<i<j<a.size)。因为题目要求i的下标要比j小,这就意味着我们要先找到一个比较小的值记为a_{i},然后在下标i后的区域找一个最大值a_{j},当找到一个比a_{i}更小的值时,让a_{j}-a_{i}获得一个在当前a_{i}后的区域相减的最大差值,然后更新a_{i}并重复前面的过程。(更新a_{i}的原因是,在找到1个比a_{i}更小的值b后,在b后面区域中的最大值a_{j}a_{i}进行相减一定不如a_{j}-b的差值大,而题目需要求最大差值,所以需要更新a_{i})。

3.代码思路

a:用于存储当前输入到数组的数。

mi:存储当前区域的最小值。

ma:存储当前区域的最大值。

b:用于存储上一个mi的值。

ans:存储相减获得的差值。

        在输入完组数和数组长度后,将输入到数组的对应的元素存入a,将mi值更新。若a的值与mi值相等,说明mi值被更新,进入了一个新的区域,需要将ans和最大值ma-b进行比较并更新ans,然后再将ma初始化,再将当前的mi存入b进行保存.若a值与mi值不相等则不用进行上述操作。再然后更新ma,反复循环直至数组元素全部输入完成。在跳出输入的循环后,在进行一次ans和ma-b比较并更新ans.(a==mi时,进入新区域,进行更新,若退出时没有进入新区域,则需要在退出后手动更新一次).判断ans是否等于0,若不相等则说明有最大差值,直接输出.否则按题目要求输出-1( 因为a_{j}\geq a _{i},所以当无最大差值时ans=0)。

4.代码实现

#include<iostream>
#include<cstdio>

using namespace std;
const int Mi=0x3f3f3f3f,Ma=-100000;

int main()
{
    int T;
    cin >>T;
    while(T--)
    {
        int n;
        cin >>n;
        int a,b;
        int  mi=Mi,ma=Ma,ans=0;
        for(int i=0;i<n;i++)
        {
            scanf("%d",&a);
            mi=min(mi,a);
            if(a==mi)    ans=max(ans,ma-b),ma=Ma,b=mi;///更新ans,初始化ma,b更新为当前mi
            ma=max(ma,a);
        }
        ans=max(ans,ma-b);///手动更新
        if(ans==0) 
        {
            cout <<-1 <<endl;
        }
        else 
        {
            cout <<ans <<endl;
        }
    }
    return 0;
}
  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,让我来解答您的问题。 首先,我们需要使用OpenCV库和C++语言来实现您的要求。以下是大致的代码实现过程: ```cpp // 读取灰度图像 cv::Mat res = cv::imread("res.png", cv::IMREAD_GRAYSCALE); // 轮廓检测 std::vector<std::vector<cv::Point>> contours; cv::findContours(res, contours, cv::RETR_EXTERNAL, cv::CHAIN_APPROX_SIMPLE); // 遍历每个轮廓 for (const auto& contour : contours) { // 找到轮廓中心 cv::Moments moments = cv::moments(contour); cv::Point center(moments.m10 / moments.m00, moments.m01 / moments.m00); // 计算每个交点的位置 std::vector<cv::Point> intersections; for (int i = 0; i < 180; i += 2) { double angle = i * CV_PI / 180.0; double cosAngle = std::cos(angle); double sinAngle = std::sin(angle); double maxDist = std::sqrt(std::pow(res.cols, 2) + std::pow(res.rows, 2)); cv::Point endpoint(center.x + maxDist * cosAngle, center.y + maxDist * sinAngle); cv::Point intersection; if (cv::intersectLinePolyline(center, endpoint, contour, intersection)) { intersections.push_back(intersection); } } // 遍历每个交点 for (const auto& intersection : intersections) { // 计算正负方向的像素值 std::vector<uchar> positivePixels, negativePixels; for (int i = 1; i <= 5; i++) { cv::Point positivePoint(intersection.x + i * (center.x - intersection.x) / 5, intersection.y + i * (center.y - intersection.y) / 5); cv::Point negativePoint(intersection.x - i * (center.x - intersection.x) / 5, intersection.y - i * (center.y - intersection.y) / 5); if (positivePoint.x >= 0 && positivePoint.x < res.cols && positivePoint.y >= 0 && positivePoint.y < res.rows) { positivePixels.push_back(res.at<uchar>(positivePoint)); } if (negativePoint.x >= 0 && negativePoint.x < res.cols && negativePoint.y >= 0 && negativePoint.y < res.rows) { negativePixels.push_back(res.at<uchar>(negativePoint)); } } // 计算灰度值最大值和最小值的差值 if (!positivePixels.empty() && !negativePixels.empty()) { int diff = *std::max_element(positivePixels.begin(), positivePixels.end()) - *std::min_element(negativePixels.begin(), negativePixels.end()); // 根据差值大小应用伪彩色 cv::Mat colorMap; cv::applyColorMap(cv::Mat(1, 1, CV_8UC1, cv::Scalar(diff)), colorMap, cv::COLORMAP_JET); cv::Vec3b color = colorMap.at<cv::Vec3b>(0, 0); // 在原图像上绘制伪彩色 cv::circle(res, intersection, 1, cv::Scalar(color[0], color[1], color[2]), 1); } } } // 显示处理后的图像 cv::imshow("result", res); cv::waitKey(0); ``` 以上代码实现了您的要求,具体实现过程如下: 1. 使用OpenCV库读取灰度图像。 2. 对图像进行轮廓检测,得到所有轮廓的坐标集合。 3. 遍历每个轮廓,计算轮廓中心。 4. 对每个轮廓中心,计算和轮廓的180个交点的位置。 5. 遍历每个交点,计算正负方向的5个像素的灰度值。 6. 计算正负方向像素灰度值最大值和最小值的差值。 7. 根据差值大小应用伪彩色。 8. 在原图像上绘制伪彩色。 9. 显示处理后的图像。 以上就是实现您的要求的大致过程,希望能对您有所帮助。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值