UVAL 4728 Squares(旋转卡壳)

本文介绍了一种名为旋转卡壳的算法,通过计算构成三角形的面积来寻找对踵点,以此实现快速处理。该算法在处理过程中涉及到了凸包构建、点排序等步骤,并通过具体代码展示了算法的应用。

Squares

【题目链接】Squares

【题目类型】旋转卡壳

&题解:

听着算法名字,感觉挺难,仔细一看之后,发现其实很简单,就是依靠所构成三角行面积来快速的找对踵点,就可以省去很多的复杂度了.旋转的复杂度是O(n),之后还有计算每条边对应的对踵点复杂度平均大约O(n/2)在实际中也许可以更快

&代码:

#include <cstdio>
#include <cstring>
#include <algorithm>
#include <vector>
#include <cmath>
using namespace std;

struct Point {
    int x,y;
    Point(int x=0,int y=0): x(x),y(y) {}
};
typedef Point Vector;
Vector operator - (const Vector& A,const Vector& B) {return Vector(A.x-B.x , A.y-B.y);}
bool operator == (const Point& a,const Point& b) {return a.x==b.x&&a.y==b.y;}
bool operator < (const Point& a,const Point& b) {return a.x<b.x||(a.x==b.x&&a.y<b.y);}
int Cross(Vector A,Vector B) {return A.x*B.y - A.y*B.x;}
int Dist2(const Point& a,const Point& b) {return (a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y);}

vector<Point> ConvexHull(vector<Point> p) {
    sort(p.begin(),p.end());
    p.erase(unique(p.begin(),p.end()) , p.end());
    int n=p.size(), m=0;
    vector<Point> ch(n+1);
    for(int i=0; i<n; i++) {
        while(m>1&&Cross(ch[m-1]-ch[m-2],p[i]-ch[m-1])<=0) m--;
        ch[m++]=p[i];
    }
    int k=m;
    for(int i=n-2; i>=0; i--) {
        while(m>k&&Cross(ch[m-1]-ch[m-2],p[i]-ch[m-1])<=0) m--;
        ch[m++]=p[i];
    }
    if(m>1) m--;
    ch.resize(m);
    return ch;
}

int diameter2(vector<Point>& points) {
    vector<Point> p=ConvexHull(points);
    int n=p.size();
    if(n==1) return 0;
    if(n==2) return Dist2(p[0] , p[1]);
    p.push_back(p[0]);
    int ans=0;
    for(int u=0, v=1; u<n; u++) {
        for(;;) {
            int diff = Cross(p[u+1]-p[u] , p[v+1]-p[v]);
            if( diff<=0 ) {
                ans=max(ans , Dist2(p[u],p[v]));
                //2个三角形面积相等
                if(diff==0) ans=max(ans, Dist2(p[u], p[v+1]));
                break;
            }
            v=(v+1)%n;
        }
    }
    return ans;
}

int main() {
    freopen("E:1.in","r",stdin);
    int T;
    scanf("%d",&T);
    while(T--) {
        int n;
        scanf("%d" ,&n);
        vector<Point> po;
        for(int i=0; i<n; i++) {
            int x,y,w;
            scanf("%d%d%d",&x,&y,&w);
            po.push_back(Point(x,y));
            po.push_back(Point(x+w,y));
            po.push_back(Point(x,y+w));
            po.push_back(Point(x+w,y+w));
        }
        printf("%d\n", diameter2(po));
    }
    return 0;
}

转载于:https://www.cnblogs.com/s1124yy/p/6783304.html

package com.example.ball.ui.activity; import android.graphics.Color; import android.os.Build; import android.os.Bundle; import android.util.Log; import android.util.Size; import android.view.View; import android.widget.TextView; import androidx.annotation.NonNull; import androidx.annotation.RequiresApi; import androidx.appcompat.app.AppCompatActivity; import androidx.camera.core.CameraSelector; import androidx.camera.core.ImageAnalysis; import androidx.camera.core.ImageProxy; import androidx.camera.core.Preview; import androidx.camera.lifecycle.ProcessCameraProvider; import androidx.camera.view.PreviewView; import androidx.core.content.ContextCompat; import com.example.ball.R; import com.google.common.util.concurrent.ListenableFuture; import java.nio.ByteBuffer; import java.util.HashMap; import java.util.Map; import java.util.concurrent.ExecutionException; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; public class CameraActivity extends AppCompatActivity { private static final String TAG = "ColorRecognition"; private static final int SAMPLE_SIZE = 5; // 采样区域半径 private static final int COLOR_TOLERANCE = 80; // 颜色匹配容差 // 预设的10种颜色及其名称 private static final Map<Integer, String> PRESET_COLORS = new HashMap<Integer, String>() {{ put(Color.RED, "红色"); put(Color.GREEN, "绿色"); put(Color.BLUE, "蓝色"); put(Color.YELLOW, "黄色"); put(Color.CYAN, "青色"); put(Color.MAGENTA, "品红"); put(0xFFFFA500, "橙色"); // 橙色 put(0xFF800080, "紫色"); // 紫色 put(0xFFFFC0CB, "粉色"); // 粉色 put(0xFFA52A2A, "棕色"); // 棕色 }}; private PreviewView previewView; private View targetArea; private View colorPreview; private TextView tvColorName; private TextView tvColorInfo; private TextView tvDetectionStatus; private ExecutorService cameraExecutor; private int targetX = 0; // 目标区域中心X坐标 private int targetY = 0; // 目标区域中心Y坐标 @RequiresApi(api = Build.VERSION_CODES.M) @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_camera); previewView = findViewById(R.id.previewView); targetArea = findViewById(R.id.targetArea); colorPreview = findViewById(R.id.colorPreview); tvColorName = findViewById(R.id.tvColorName); tvColorInfo = findViewById(R.id.tvColorInfo); tvDetectionStatus = findViewById(R.id.tvDetectionStatus); cameraExecutor = Executors.newSingleThreadExecutor(); // 设置目标区域位置(屏幕中心) previewView.post(() -> { targetX = previewView.getWidth() / 2; targetY = previewView.getHeight() / 2; updateTargetPosition(); }); // 启动摄像头 if (ContextCompat.checkSelfPermission(this, android.Manifest.permission.CAMERA) == android.content.pm.PackageManager.PERMISSION_GRANTED) { startCamera(); } else { requestPermissions(new String[]{android.Manifest.permission.CAMERA}, 1); } } private void updateTargetPosition() { targetArea.setX(targetX - targetArea.getWidth() / 2f); targetArea.setY(targetY - targetArea.getHeight() / 2f); } private void startCamera() { ListenableFuture<ProcessCameraProvider> cameraProviderFuture = ProcessCameraProvider.getInstance(this); cameraProviderFuture.addListener(() -> { try { ProcessCameraProvider cameraProvider = cameraProviderFuture.get(); // 配置预览 Preview preview = new Preview.Builder().build(); preview.setSurfaceProvider(previewView.getSurfaceProvider()); // 配置图像分析 ImageAnalysis imageAnalysis = new ImageAnalysis.Builder() .setTargetResolution(new Size(640, 480)) // 优化性能 .setBackpressureStrategy(ImageAnalysis.STRATEGY_KEEP_ONLY_LATEST) .build(); imageAnalysis.setAnalyzer(cameraExecutor, new ColorAnalyzer()); // 选择后置摄像头 CameraSelector cameraSelector = new CameraSelector.Builder() .requireLensFacing(CameraSelector.LENS_FACING_BACK) .build(); // 绑定用例 cameraProvider.bindToLifecycle(this, cameraSelector, preview, imageAnalysis); } catch (ExecutionException | InterruptedException e) { Log.e(TAG, "Camera setup error: " + e.getMessage()); } }, ContextCompat.getMainExecutor(this)); } private class ColorAnalyzer implements ImageAnalysis.Analyzer { @Override public void analyze(@NonNull ImageProxy image) { // 坐标转换(预览坐标 → 图像坐标) int imgWidth = image.getWidth(); int imgHeight = image.getHeight(); int previewWidth = previewView.getWidth(); int previewHeight = previewView.getHeight(); int imgX = (int) (targetX * (imgWidth / (float) previewWidth)); int imgY = (int) (targetY * (imgHeight / (float) previewHeight)); // 从YUV数据提取颜色 int color = extractColor(image, imgX, imgY); // 更新UI runOnUiThread(() -> updateColorDisplay(color)); image.close(); } private int extractColor(ImageProxy image, int centerX, int centerY) { ImageProxy.PlaneProxy[] planes = image.getPlanes(); int rSum = 0, gSum = 0, bSum = 0; int count = 0; // 采样区域:中心点周围5x5像素 for (int dy = -SAMPLE_SIZE; dy <= SAMPLE_SIZE; dy++) { for (int dx = -SAMPLE_SIZE; dx <= SAMPLE_SIZE; dx++) { int x = centerX + dx; int y = centerY + dy; if (x >= 0 && x < image.getWidth() && y >= 0 && y < image.getHeight()) { int color = getRGBFromYUV(planes, x, y, image.getWidth()); rSum += Color.red(color); gSum += Color.green(color); bSum += Color.blue(color); count++; } } } // 计算平均颜色 if (count > 0) { return Color.rgb(rSum / count, gSum / count, bSum / count); } return Color.BLACK; } // 高效YUV转RGB private int getRGBFromYUV(ImageProxy.PlaneProxy[] planes, int x, int y, int width) { ByteBuffer yBuffer = planes[0].getBuffer(); ByteBuffer uBuffer = planes[1].getBuffer(); ByteBuffer vBuffer = planes[2].getBuffer(); // 计算偏移量 int yOffset = y * planes[0].getRowStride() + x * planes[0].getPixelStride(); int uvX = x / 2; int uvY = y / 2; int uOffset = uvY * planes[1].getRowStride() + uvX * planes[1].getPixelStride(); int vOffset = uvY * planes[2].getRowStride() + uvX * planes[2].getPixelStride(); // 获取YUV值 int yVal = yBuffer.get(yOffset) & 0xFF; int uVal = uBuffer.get(uOffset) & 0xFF; int vVal = vBuffer.get(vOffset) & 0xFF; // YUV转RGB公式 int r = clamp((int) (yVal + 1.402 * (vVal - 128))); int g = clamp((int) (yVal - 0.34414 * (uVal - 128) - 0.71414 * (vVal - 128))); int b = clamp((int) (yVal + 1.772 * (uVal - 128))); return Color.rgb(r, g, b); } private int clamp(int value) { return Math.max(0, Math.min(255, value)); } } private void updateColorDisplay(int detectedColor) { // 更新颜色预览 colorPreview.setBackgroundColor(detectedColor); // 获取RGB值 int r = Color.red(detectedColor); int g = Color.green(detectedColor); int b = Color.blue(detectedColor); String rgb = String.format("RGB: %d, %d, %d", r, g, b); tvColorInfo.setText(rgb); // 匹配预设颜色 String colorName = "未设定颜色"; for (Map.Entry<Integer, String> entry : PRESET_COLORS.entrySet()) { int presetColor = entry.getKey(); int pr = Color.red(presetColor); int pg = Color.green(presetColor); int pb = Color.blue(presetColor); // 计算颜色距离 double distance = Math.sqrt( Math.pow(r - pr, 2) + Math.pow(g - pg, 2) + Math.pow(b - pb, 2) ); if (distance < COLOR_TOLERANCE) { colorName = entry.getValue(); break; } } tvColorName.setText(colorName); tvDetectionStatus.setText(colorName.equals("未设定颜色") ? "识别区域" : "检测到: " + colorName); } @Override protected void onDestroy() { super.onDestroy(); if (cameraExecutor != null) { cameraExecutor.shutdown(); } } } 以上预设的颜色由于识别不够精准导致需求不符,请改成预设颜色范围
08-03
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值