【循环测试试题4】小X与正方形 (square)

文章介绍了如何利用C++编程解决一个关于围棋棋盘的问题,即给定三个棋子的位置,找出最后一个棋子放置的位置,使得它们构成一个正方形的四个顶点。代码使用欧几里得距离计算方法寻找符合条件的坐标。

题目描述
小X的老师很喜欢围棋。众所周知,围棋的棋盘有19行19列。为方便起见,我们把这些行列按顺序编号为1~19,并用(x, y)表示第x列第y行的位置。例如下图中,A用(16,4)表示,B用(14, 3)表示。

现在老师让小X在棋盘上放4枚棋子,要求这4枚棋子组成一个正方形的四个顶点。但是小X喜欢三角形,不喜欢正方形,于是只放了3枚就跑出去玩去了。那么这最后的棋子就交给你来放了,请求出这枚棋子应该放在哪里?

输入
输入数据仅有一行包含6个用空格隔开的正整数x1, y1, x2, y2, x3, y3, 表示三枚棋子的位置为(x1, y1), (x2, y2), (x3, y3)。

输出
输出一行包含两个正整数x和 y,两数之间用一个空格隔开;表示若将最后一枚棋子放在位置(x, y),它与之前的三枚棋子能组成一个正方形的四个顶点。数据保证方案唯一。

样例输入 复制
4 4 4 16 16 16

样例输出 复制
16 4

数据范围限制
对于80%的数据,正方形的四条边与网格线平行。
其中40%的数据,除上一条以外,还保证最后一枚棋子在正方形的左上角。
对于100%的数据,1<=x1, y1, x2, y2, x3, y3<=19,所有数据保证方案唯一。

提示
样例输入2
2 1 4 2 3 4
 
样例输出2
1 3

样例解释1
如上图所示,最后一枚棋子应放在A (16, 4)处。

样例解释2
注意考虑正方形的四条边不与棋盘上的网格线平行的情况,这种情况你也可以无视它,因为这种情况只占本题20%的分数。

上代码:

#include<bits/stdc++.h>
using namespace std;
int juli(int x1,int y1,int x2,int y2)
{
    return ((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2));
}
int main()
{
    int x1,y1,x2,y2,x3,y3,a,b,c;
    cin>>x1>>y1>>x2>>y2>>x3>>y3;
    a=juli(x1,y1,x2,y2);
    b=juli(x1,y1,x3,y3);
    c=juli(x2,y2,x3,y3);
    int d;
    if(b>a)
    {
        swap(x2,x3);
        swap(y2,y3);
        d=a;
    }
    else if(c>a)
    {
        swap(x1,x3);
        swap(y1,y3);
        d=a;
    }
    else
    d=b;
    for(int i=1;i<=19;i++)
        for(int j=1;j<=19;j++)
        {
            int e=juli(i,j,x1,y1),
                f=juli(i,j,x2,y2);
            if(e==d&&f==d&&(i!=x3||j!=y3))
            {
                cout<<i<<' '<<j;
                return 0;
            }
        }
}

import sensor import time import random import math # 全局状态变量 state = 0 # 0: 等待启动, 1: 第一轮测量, 2: 第二轮测量, 3: 编号输入测量, 4: 角度测量 remaining_targets = [1, 2, 3, 4] # 剩余目标物编号 current_target = None # 当前目标物 指定编号 = 0 # 用户输入的指定编号 # 设置VGA画面,并裁剪中间的画面 sensor.reset() sensor.set_pixformat(sensor.GRAYSCALE) sensor.set_framesize(sensor.VGA) sensor.set_windowing((200,240)) sensor.skip_frames(time=2000) clock = time.clock() # Tracks FPS. CENTER_X = 200//2 CENTER_Y = 240//2 # 边框的真实长度,单位mm FRAME_WIDTH_MM = 176 # 校准的数据 # 例如: 当距离是1400mm时,边框宽度为82像素 # DISTANCE_MM_1 = 1100 # FRAME_WIDTH_PIXEL_1 = 104 DISTANCE_MM_2 = 1400 FRAME_WIDTH_PIXEL_2 = 82 # DISTANCE_MM_3 = 1800 # FRAME_WIDTH_PIXEL_3 = 64 # 目标物数据(假设) 目标物数据 = { 1: {"name": "目标物1", "color": (0, 150)}, 2: {"name": "目标物2", "color": (0, 150)}, 3: {"name": "目标物3", "color": (0, 150)}, 4: {"name": "目标物4", "color": (0, 150)} } # 数字模板(简化版,实际应用中可能需要更复杂的模板匹配) 数字模板 = { 1: "1", 2: "2", 3: "3", 4: "4" } def find_center_min_blob(blobs): # 找中间最小的色块 blob = None min_area = 100000 for b in blobs: if abs(b.cx()-CENTER_X)+ abs(b.cy()-CENTER_Y) > 50: continue if b.area() > min_area: continue blob = b min_area = b.area() return blob def find_center_max_blob(blobs): # 找中间最大的色块 blob = None max_area = 0 for b in blobs: if abs(b.cx()-CENTER_X)+ abs(b.cy()-CENTER_Y) > 50: continue if b.area() < max_area: continue blob = b max_area = b.area() return blob def find_min_square(blobs): # 找最小面积的正方形 min_square = None min_area = float('inf') # 初始化为无穷大 # 调试信息:显示找到的色块数量 print(f"找到的色块数量: {len(blobs)}") for b in blobs: # 对于黑色正方形,降低面积过滤阈值 if b.area() < 5: # 进一步降低最小面积阈值 continue # 假设正方形的宽高比接近1 aspect_ratio = max(b.w(), b.h()) / min(b.w(), b.h()) if min(b.w(), b.h()) > 0 else 0 # 对于小正方形,宽高比判断可以更宽松 if aspect_ratio > 1.3: # 稍微放宽宽高比限制 continue if b.area() < min_area: min_area = b.area() min_square = b print(f"临时最小正方形: 面积={b.area()}, 宽={b.w()}, 高={b.h()}, 宽高比={aspect_ratio:.2f}") # 调试信息 if min_square: print(f"最终最小正方形: 面积={min_square.area()}, 宽={min_square.w()}, 高={min_square.h()}") else: print("未找到符合条件的正方形") return min_square def recognize_number(img, roi): # 识别数字(简化版) # 实际应用中可能需要OCR或模板匹配 # 这里返回一个随机数作为示例 return random.randint(1, 4) def calculate_angle(blob): # 计算物体轴线的夹角 # 假设通过宽高比来估算角度 aspect_ratio = blob.w() / blob.h() if blob.h() > 0 else 1 angle = math.atan(aspect_ratio) * 180 / math.pi return min(max(angle, 30), 60) # 限制在30-60度之间 def start_measurement(): global state, current_target, remaining_targets if state == 0: # 第一轮测量:随机取一个目标物 if remaining_targets: current_target = random.choice(remaining_targets) remaining_targets.remove(current_target) state = 1 print(f"第一轮测量:已选择目标物 {current_target}") else: print("没有可用目标物") elif state == 1: # 第二轮测量:从剩余目标物中再随机取一个 if remaining_targets: current_target = random.choice(remaining_targets) remaining_targets.remove(current_target) state = 2 print(f"第二轮测量:已选择目标物 {current_target}") else: print("没有可用目标物") elif state == 2: # 第三轮测量:等待输入编号 state = 3 print("请输入要测量的正方形编号(1-4):") elif state == 3: # 第三轮测量:等待输入编号后的执 if 指定编号 in 目标物数据: current_target = 指定编号 state = 4 print(f"第三轮测量:已选择目标物 {current_target}") else: print("无效的编号,请重新输入") elif state == 4: # 第四轮测量:角度测量准备 state = 5 print("第四轮测量:准备角度测量") elif state == 5: # 第四轮测量:角度测量 state = 0 print("第四轮测量:角度测量完成") # 主循环 while True: clock.tick() img = sensor.snapshot() # 显示状态信息 img.draw_string(10, 10, f"状态: {state}", color=(255, 0, 0)) if current_target: img.draw_string(10, 25, f"当前目标: {current_target}", color=(255, 0, 0)) img.draw_string(10, 40, "按任意键启动测量", color=(255, 0, 0)) # 检测按键(假设通过串口或其他方式输入) # 这里简化为每5秒自动启动,实际应用中需替换为真实的输入检测 # if 检测到按键: # start_measurement() # 模拟按键输入(用于测试) if time.time() % 5 < 0.1 and state == 0: start_measurement() # 找白色色块,黑色边框内部 frames = img.find_blobs([(150,256)]) frame_blob = find_center_min_blob(frames) if not frame_blob: print("NO FRAME") continue # 计算距离 distance = DISTANCE_MM_2*FRAME_WIDTH_PIXEL_2/frame_blob.w() # 缩小roi,避免黑框的黑边 frame_roi = (frame_blob.x()+5, frame_blob.y()+5, frame_blob.w()-10, frame_blob.h()-10) if frame_roi[2] <= 0 or frame_roi[3] <= 0: print("ROI ERROR") continue # print(frame_roi) # 找黑色色块,目标物体 objs = img.find_blobs([(0,150)], roi=frame_roi) obj_blob = find_center_max_blob(objs) if not obj_blob: print("NO OBJS") continue # 根据状态执不同的测量任务 if state == 1 or state == 2: # 任务1和2:找最小面积正方形 # 调整色块检测参数,针对黑色正方形优化 # (0, 100) 更适合检测黑色 squares = img.find_blobs([(0, 100)], roi=frame_roi, pixels_threshold=2, area_threshold=2) min_square = find_min_square(squares) if min_square: # 计算正方形的x(假设x为宽度) square_x_mm = min_square.w()/frame_blob.w()*FRAME_WIDTH_MM print(f"距离D: {distance:.2f}mm, 最小正方形x: {square_x_mm:.2f}mm") img.draw_string(10, 60, f"D: {distance:.2f}mm", color=(255, 0, 0)) img.draw_string(10, 75, f"最小正方形x: {square_x_mm:.2f}mm", color=(255, 0, 0)) img.draw_rectangle(min_square.rect(), color=(0, 255, 0)) else: # 如果没找到最小正方形,尝试极低阈值 squares = img.find_blobs([(0, 100)], roi=frame_roi, pixels_threshold=1, area_threshold=1) min_square = find_min_square(squares) if min_square: square_x_mm = min_square.w()/frame_blob.w()*FRAME_WIDTH_MM print(f"极低阈值下找到: 距离D: {distance:.2f}mm, 最小正方形x: {square_x_mm:.2f}mm") img.draw_string(10, 60, f"D: {distance:.2f}mm", color=(255, 0, 0)) img.draw_string(10, 75, f"最小正方形x: {square_x_mm:.2f}mm", color=(255, 0, 0)) img.draw_rectangle(min_square.rect(), color=(0, 255, 0)) else: print("未找到任何正方形色块") elif state == 4: # 任务3:指定编号正方形 # 使用优化的黑色正方形检测参数 squares = img.find_blobs([(0, 100)], roi=frame_roi, pixels_threshold=2, area_threshold=2) # 找最小正方形 min_square = find_min_square(squares) if min_square: # 识别数字 number = recognize_number(img, min_square.rect()) print(f"识别到的编号: {number}") if number == 指定编号: # 计算指定编号正方形的x square_x_mm = min_square.w()/frame_blob.w()*FRAME_WIDTH_MM print(f"距离D: {distance:.2f}mm, 编号{指定编号}正方形x: {square_x_mm:.2f}mm") img.draw_string(10, 60, f"D: {distance:.2f}mm", color=(255, 0, 0)) img.draw_string(10, 75, f"编号{指定编号}正方形x: {square_x_mm:.2f}mm", color=(255, 0, 0)) else: print(f"识别到的编号{number}指定编号{指定编号}不匹配") else: print("未找到正方形色块,无法识别编号") elif state == 5: # 任务4:角度测量 # 先找到最小正方形 squares = img.find_blobs([(0, 100)], roi=frame_roi, pixels_threshold=2, area_threshold=2) min_square = find_min_square(squares) if min_square: angle = calculate_angle(min_square) # 计算倾斜状态下的正方形x square_x_mm = min_square.w()/frame_blob.w()*FRAME_WIDTH_MM / math.cos(math.radians(angle)) print(f"角度θ: {angle:.2f}度, 正方形x: {square_x_mm:.2f}mm") img.draw_string(10, 60, f"角度θ: {angle:.2f}度", color=(255, 0, 0)) img.draw_string(10, 75, f"正方形x: {square_x_mm:.2f}mm", color=(255, 0, 0)) else: print("未找到正方形色块,无法进角度测量") # 计算物体边长(原有功能) obj_w_mm = obj_blob.w()/frame_blob.w()*FRAME_WIDTH_MM # 原有形状识别功能 # print(frame_blob.w()) # print(obj_blob.density()) # if 0.9 < obj_blob.density() : # print("矩形") # elif 0.6 < obj_blob.density(): # print("圆形") # elif 0.4 < obj_blob.density(): # print("三角形形") # else: # print("无法识别到形状") # 绘制边框和目标 img.draw_rectangle(frame_blob.rect()) img.draw_rectangle(obj_blob.rect()) # 检测用户输入(假设通过串口接收) # 这里简化处理,实际应用中需根据硬件情况实现 # 如果在状态3,接收用户输入的编号 if state == 3: # 模拟用户输入(实际应用中替换为真实输入检测) # 这里每2秒自动输入一个随机编号 if time.time() % 2 < 0.1: 指定编号 = random.randint(1, 4) print(f"用户输入编号: {指定编号}") start_measurement() 解释一下各个代码
08-02
import sensor import time import random import math # 全局状态变量 state = 0 # 0: 等待启动, 1: 第一轮测量, 2: 第二轮测量, 3: 编号输入测量, 4: 角度测量 remaining_targets = [1, 2, 3, 4] # 剩余目标物编号 current_target = None # 当前目标物 指定编号 = 0 # 用户输入的指定编号 # 设置VGA画面,并裁剪中间的画面 sensor.reset() sensor.set_pixformat(sensor.GRAYSCALE) sensor.set_framesize(sensor.VGA) sensor.set_windowing((200,240)) sensor.skip_frames(time=2000) clock = time.clock() # Tracks FPS. CENTER_X = 200//2 CENTER_Y = 240//2 # 边框的真实长度,单位mm FRAME_WIDTH_MM = 176 # 校准的数据 # 例如: 当距离是1400mm时,边框宽度为82像素 # DISTANCE_MM_1 = 1100 # FRAME_WIDTH_PIXEL_1 = 104 DISTANCE_MM_2 = 1400 FRAME_WIDTH_PIXEL_2 = 82 # DISTANCE_MM_3 = 1800 # FRAME_WIDTH_PIXEL_3 = 64 # 目标物数据(假设) 目标物数据 = { 1: {"name": "目标物1", "color": (0, 150)}, 2: {"name": "目标物2", "color": (0, 150)}, 3: {"name": "目标物3", "color": (0, 150)}, 4: {"name": "目标物4", "color": (0, 150)} } # 数字模板(简化版,实际应用中可能需要更复杂的模板匹配) 数字模板 = { 1: "1", 2: "2", 3: "3", 4: "4" } def find_center_min_blob(blobs): # 找中间最小的色块 blob = None min_area = 100000 for b in blobs: if abs(b.cx()-CENTER_X)+ abs(b.cy()-CENTER_Y) > 50: continue if b.area() > min_area: continue blob = b min_area = b.area() return blob def find_center_max_blob(blobs): # 找中间最大的色块 blob = None max_area = 0 for b in blobs: if abs(b.cx()-CENTER_X)+ abs(b.cy()-CENTER_Y) > 50: continue if b.area() < max_area: continue blob = b max_area = b.area() return blob def find_min_square(blobs): # 找最小面积的正方形 min_square = None min_area = float('inf') # 初始化为无穷大 # 调试信息:显示找到的色块数量 print(f"找到的色块数量: {len(blobs)}") for b in blobs: # 对于黑色正方形,降低面积过滤阈值 if b.area() < 5: # 进一步降低最小面积阈值 continue # 假设正方形的宽高比接近1 aspect_ratio = max(b.w(), b.h()) / min(b.w(), b.h()) if min(b.w(), b.h()) > 0 else 0 # 对于小正方形,宽高比判断可以更宽松 if aspect_ratio > 1.3: # 稍微放宽宽高比限制 continue if b.area() < min_area: min_area = b.area() min_square = b print(f"临时最小正方形: 面积={b.area()}, 宽={b.w()}, 高={b.h()}, 宽高比={aspect_ratio:.2f}") # 调试信息 if min_square: print(f"最终最小正方形: 面积={min_square.area()}, 宽={min_square.w()}, 高={min_square.h()}") else: print("未找到符合条件的正方形") return min_square def recognize_number(img, roi): # 识别数字(简化版) # 实际应用中可能需要OCR或模板匹配 # 这里返回一个随机数作为示例 return random.randint(1, 4) def calculate_angle(blob): # 计算物体轴线的夹角 # 假设通过宽高比来估算角度 aspect_ratio = blob.w() / blob.h() if blob.h() > 0 else 1 angle = math.atan(aspect_ratio) * 180 / math.pi return min(max(angle, 30), 60) # 限制在30-60度之间 def start_measurement(): global state, current_target, remaining_targets if state == 0: # 第一轮测量:随机取一个目标物 if remaining_targets: current_target = random.choice(remaining_targets) remaining_targets.remove(current_target) state = 1 print(f"第一轮测量:已选择目标物 {current_target}") else: print("没有可用目标物") elif state == 1: # 第二轮测量:从剩余目标物中再随机取一个 if remaining_targets: current_target = random.choice(remaining_targets) remaining_targets.remove(current_target) state = 2 print(f"第二轮测量:已选择目标物 {current_target}") else: print("没有可用目标物") elif state == 2: # 第三轮测量:等待输入编号 state = 3 print("请输入要测量的正方形编号(1-4):") elif state == 3: # 第三轮测量:等待输入编号后的执 if 指定编号 in 目标物数据: current_target = 指定编号 state = 4 print(f"第三轮测量:已选择目标物 {current_target}") else: print("无效的编号,请重新输入") elif state == 4: # 第四轮测量:角度测量准备 state = 5 print("第四轮测量:准备角度测量") elif state == 5: # 第四轮测量:角度测量 state = 0 print("第四轮测量:角度测量完成") # 主循环 while True: clock.tick() img = sensor.snapshot() # 显示状态信息 img.draw_string(10, 10, f"状态: {state}", color=(255, 0, 0)) if current_target: img.draw_string(10, 25, f"当前目标: {current_target}", color=(255, 0, 0)) img.draw_string(10, 40, "按任意键启动测量", color=(255, 0, 0)) # 检测按键(假设通过串口或其他方式输入) # 这里简化为每5秒自动启动,实际应用中需替换为真实的输入检测 # if 检测到按键: # start_measurement() # 模拟按键输入(用于测试) if time.time() % 5 < 0.1 and state == 0: start_measurement() # 找白色色块,黑色边框内部 frames = img.find_blobs([(150,256)]) frame_blob = find_center_min_blob(frames) if not frame_blob: print("NO FRAME") continue # 计算距离 distance = DISTANCE_MM_2*FRAME_WIDTH_PIXEL_2/frame_blob.w() # 缩小roi,避免黑框的黑边 frame_roi = (frame_blob.x()+5, frame_blob.y()+5, frame_blob.w()-10, frame_blob.h()-10) if frame_roi[2] <= 0 or frame_roi[3] <= 0: print("ROI ERROR") continue # print(frame_roi) # 找黑色色块,目标物体 objs = img.find_blobs([(0,150)], roi=frame_roi) obj_blob = find_center_max_blob(objs) if not obj_blob: print("NO OBJS") continue # 根据状态执不同的测量任务 if state == 1 or state == 2: # 任务1和2:找最小面积正方形 # 调整色块检测参数,针对黑色正方形优化 # (0, 100) 更适合检测黑色 squares = img.find_blobs([(0, 100)], roi=frame_roi, pixels_threshold=2, area_threshold=2) min_square = find_min_square(squares) if min_square: # 计算正方形的x(假设x为宽度) square_x_mm = min_square.w()/frame_blob.w()*FRAME_WIDTH_MM print(f"距离D: {distance:.2f}mm, 最小正方形x: {square_x_mm:.2f}mm") img.draw_string(10, 60, f"D: {distance:.2f}mm", color=(255, 0, 0)) img.draw_string(10, 75, f"最小正方形x: {square_x_mm:.2f}mm", color=(255, 0, 0)) img.draw_rectangle(min_square.rect(), color=(0, 255, 0)) else: # 如果没找到最小正方形,尝试极低阈值 squares = img.find_blobs([(0, 100)], roi=frame_roi, pixels_threshold=1, area_threshold=1) min_square = find_min_square(squares) if min_square: square_x_mm = min_square.w()/frame_blob.w()*FRAME_WIDTH_MM print(f"极低阈值下找到: 距离D: {distance:.2f}mm, 最小正方形x: {square_x_mm:.2f}mm") img.draw_string(10, 60, f"D: {distance:.2f}mm", color=(255, 0, 0)) img.draw_string(10, 75, f"最小正方形x: {square_x_mm:.2f}mm", color=(255, 0, 0)) img.draw_rectangle(min_square.rect(), color=(0, 255, 0)) else: print("未找到任何正方形色块") elif state == 4: # 任务3:指定编号正方形 # 使用优化的黑色正方形检测参数 squares = img.find_blobs([(0, 100)], roi=frame_roi, pixels_threshold=2, area_threshold=2) # 找最小正方形 min_square = find_min_square(squares) if min_square: # 识别数字 number = recognize_number(img, min_square.rect()) print(f"识别到的编号: {number}") if number == 指定编号: # 计算指定编号正方形的x square_x_mm = min_square.w()/frame_blob.w()*FRAME_WIDTH_MM print(f"距离D: {distance:.2f}mm, 编号{指定编号}正方形x: {square_x_mm:.2f}mm") img.draw_string(10, 60, f"D: {distance:.2f}mm", color=(255, 0, 0)) img.draw_string(10, 75, f"编号{指定编号}正方形x: {square_x_mm:.2f}mm", color=(255, 0, 0)) else: print(f"识别到的编号{number}指定编号{指定编号}不匹配") else: print("未找到正方形色块,无法识别编号") elif state == 5: # 任务4:角度测量 # 先找到最小正方形 squares = img.find_blobs([(0, 100)], roi=frame_roi, pixels_threshold=2, area_threshold=2) min_square = find_min_square(squares) if min_square: angle = calculate_angle(min_square) # 计算倾斜状态下的正方形x square_x_mm = min_square.w()/frame_blob.w()*FRAME_WIDTH_MM / math.cos(math.radians(angle)) print(f"角度θ: {angle:.2f}度, 正方形x: {square_x_mm:.2f}mm") img.draw_string(10, 60, f"角度θ: {angle:.2f}度", color=(255, 0, 0)) img.draw_string(10, 75, f"正方形x: {square_x_mm:.2f}mm", color=(255, 0, 0)) else: print("未找到正方形色块,无法进角度测量") # 计算物体边长(原有功能) obj_w_mm = obj_blob.w()/frame_blob.w()*FRAME_WIDTH_MM # 原有形状识别功能 # print(frame_blob.w()) # print(obj_blob.density()) # if 0.9 < obj_blob.density() : # print("矩形") # elif 0.6 < obj_blob.density(): # print("圆形") # elif 0.4 < obj_blob.density(): # print("三角形形") # else: # print("无法识别到形状") # 绘制边框和目标 img.draw_rectangle(frame_blob.rect()) img.draw_rectangle(obj_blob.rect()) # 检测用户输入(假设通过串口接收) # 这里简化处理,实际应用中需根据硬件情况实现 # 如果在状态3,接收用户输入的编号 if state == 3: # 模拟用户输入(实际应用中替换为真实输入检测) # 这里每2秒自动输入一个随机编号 if time.time() % 2 < 0.1: 指定编号 = random.randint(1, 4) print(f"用户输入编号: {指定编号}") start_measurement() 解释一下代码
08-01
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值