bzoj 2338 [HNOI2011]数矩形

bzoj <wbr>2338 <wbr>[HNOI2011]数矩形


一开始只考虑了边和坐标轴平行的矩形。。。先离散,在枚举两点做对角线,用boolean数组判断另外两点。。。

然后猛然想到各种斜矩形。果断重打。。。

还是利用矩形对角线平分的性质,求出每个点对连线的中点,排序,找矩形。

一开始2B地开了实数数组记录中点,然后发现其实除2操作根本毫无意义。。。而且实数的快排判断各种WS。。

改之。。。

然后发现对角线平分的不止有矩形还有平行四边形。。。又开了一个长度数组记录对角线长度。。。

A之。。。

以上就是被这道计几基础题完虐的过程。。。我会说因为数组少开个0还RE了一次么。。。

各种弱啊。。。



AC CODE

program hnoi_2011_day2_rectangle;
var xx,yy:array[1..1500] of int64;
    x,y,d:array[1..2250000] of int64;
    p1,p2:array[1..2250000] of longint;
    n,i,j,tot:longint;
    ans,tmp:int64;
//=========================================================================
procedure qsort(l,r:longint);
var tt,k1,k2:int64;
    i,j,t2:longint;
begin
  k1:=x[(l+r) shr 1]; k2:=y[(l+r) shr 1];
  i:=l; j:=r;
  repeat
    while (x[i]
    while (x[j]>k1) or ((x[j]=k1) and (y[j]>k2)) do dec(j);
    if i<=j then
    begin
      tt:=x[i]; x[i]:=x[j]; x[j]:=tt;
      tt:=y[i]; y[i]:=y[j]; y[j]:=tt;
      tt:=d[i]; d[i]:=d[j]; d[j]:=tt;    //记录对角线长度。
      t2:=p1[i]; p1[i]:=p1[j]; p1[j]:=t2;
      t2:=p2[i]; p2[i]:=p2[j]; p2[j]:=t2;
      inc(i); dec(j);
    end;
  until i>j;
  if l
  if i
end;
//=========================================================================
begin
  assign(input,'1.in'); reset(input);
  assign(output,'1.out'); rewrite(output);
  readln(n); tot:=0;
  for i:=1 to n do readln(xx[i],yy[i]);
  for i:=1 to n-1 do
    for j:=i+1 to n do
    begin inc(tot);
      p1[tot]:=i; p2[tot]:=j;
      d[tot]:=sqr(xx[i]-xx[j])+sqr(yy[i]-yy[j]);
      x[tot]:=xx[i]+xx[j];    //记录中点的时候直接加,不用除、、
      y[tot]:=yy[i]+yy[j];
    end; qsort(1,tot); ans:=0;
  for i:=1 to tot-1 do
  begin
    for j:=i+1 to tot do
      if x[i]=x[j] then 
      begin
        if y[i]<>y[j] then continue;
        if d[i]<>d[j] then continue;
        tmp:=(xx[p1[i]]-xx[p2[i]])*(yy[p1[j]]-yy[p2[i]])-(xx[p1[j]]-xx[p2[i]])*(yy[p1[i]]-yy[p2[i]]);  //叉积还是很好用的、、
        if tmp<0 then tmp:=-tmp; tmp:=tmp;
        if tmp>ans then ans:=tmp;
      end else break;
  end; writeln(ans);
end.

### 基于最大内切圆法的掌纹ROI提取 在计算机视觉领域,利用OpenCV可以高效地实现图像处理中的特定目标检测任务。对于掌纹ROI(感兴趣区域)提取问题,可以通过计算手掌轮廓的最大内切圆来定位并裁剪出感兴趣的区域。 以下是基于Python和OpenCV实现该方法的具体过程: #### 1. 图像预处理 为了更好地识别手掌轮廓,通常需要对原始图像进行二值化处理以及形态学操作以去除噪声[^1]。 ```python import cv2 import numpy as np def preprocess_image(image): gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY) # 转换为灰度图 blurred = cv2.GaussianBlur(gray, (5, 5), 0) # 高斯模糊去噪 _, binary = cv2.threshold(blurred, 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU) # 自适应阈值分割 kernel = np.ones((3, 3), dtype=np.uint8) morphed = cv2.morphologyEx(binary, cv2.MORPH_CLOSE, kernel) # 形态闭运算填充孔洞 return morphed ``` #### 2. 手掌轮廓提取 通过查找连通域的方式找到最大的手掌轮廓,并将其作为后续计算的基础。 ```python def find_palm_contour(binary_image): contours, _ = cv2.findContours(binary_image, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE) palm_contour = max(contours, key=cv2.contourArea) # 获取面积最大的轮廓 return palm_contour ``` #### 3. 计算最大内切圆 使用`cv2.minEnclosingCircle()`函数可以直接获得包围给定轮廓的最小外接圆中心及其半径;而最大内切圆则需进一步优化求解,在此我们假设其近似等于最小外接圆的一部分。 ```python def compute_max_inscribed_circle(palm_contour): (center_x, center_y), radius = cv2.minEnclosingCircle(palm_contour) center = (int(center_x), int(center_y)) radius = int(radius * 0.9) # 缩小一定比例模拟最大内切圆效果 return center, radius ``` #### 4. 提取ROI区域 最后依据得到的圆形参数截取出对应的矩形范围内的子图像即为目标掌纹ROI部分。 ```python def extract_roi(original_image, center, radius): x, y = center roi = original_image[y-radius:y+radius, x-radius:x+radius] return roi ``` 完整的代码流程如下所示: ```python if __name__ == "__main__": image_path = 'palm.jpg' img = cv2.imread(image_path) processed_img = preprocess_image(img) contour = find_palm_contour(processed_img) circle_center, circle_radius = compute_max_inscribed_circle(contour) roi_region = extract_roi(img, circle_center, circle_radius) cv2.imshow('Palm ROI', roi_region) cv2.waitKey(0) cv2.destroyAllWindows() ``` 上述方法能够较为精确地完成掌纹ROI的自动提取工作,适用于多种实际应用场景之中。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值