zoukankan      html  css  js  c++  java
  • luogu 1369

    给出平面上的n个点,请找出一个边与坐标轴平行的矩形,使得它的边界上有尽量多的点

    模拟退火题解
    $n^2$ 处理每行的前缀和与每列的前缀和
    退火50次即可

    #include <bits/stdc++.h>
    
    const int N = 102;
    
    int n, A[N][N];
    int sum_h[N][N], sum_l[N][N];
    int Max_n = 0, Max_m = 0;
    
    #define gc getchar()
    
    inline int read() {
        int x = 0;
        char c = gc;
        while(c < '0' || c > '9') c = gc;
        while(c >= '0' && c <= '9') x = x * 10 + c - '0', c = gc;
        return x;
    }
    
    #define DB double
    
    const DB Max_tmp = 1000, Del = 0.98;
    
    int Get_ans(int l, int r, int u, int d) {
        if(l == r && u != d) {
            return sum_l[d][l] - sum_l[u - 1][l];
        } else if(l != r && u == d) {
            return sum_h[u][r] - sum_h[u][l - 1];
        } else if(l == r && u == d) {
            return A[l][u];
        } else {
            int ret = 0;
            ret += (sum_h[u][r] - sum_h[u][l - 1])
                   +  (sum_h[d][r] - sum_h[d][l - 1])
                   +  (sum_l[d][l] - sum_l[u - 1][l])
                   +  (sum_l[d][r] - sum_l[u - 1][r]);
            if(A[u][l]) ret --;
            if(A[u][r]) ret --;
            if(A[d][l]) ret --;
            if(A[d][r]) ret --;
            return ret;
        }
    }
    
    inline int MNTH() {
        DB Now_tmp = Max_tmp;
        int l = rand() % Max_m + 1, r = rand() % Max_m + 1, u = rand() % Max_n + 1, d = rand() % Max_n + 1;
        int Now_ans = Get_ans(l, r, u, d);
        while(Now_tmp > 0.01) {
            int l_ = l, r_ = r, u_ = u, d_ = d;
            int opt = rand() % 4 + 1;
            if(opt == 1) l_ = rand() % Max_m + 1;
            else if(opt == 2) r_ = rand() % Max_m + 1;
            else if(opt == 3) u_ = rand() % Max_n + 1;
            else d_ = rand() % Max_n + 1;
            int Ls_ans = Get_ans(l_, r_, u_, d_);
            if(Ls_ans > Now_ans || (Ls_ans < Now_ans && exp((Ls_ans - Now_ans) / Now_tmp) * RAND_MAX) >= rand())
                Now_ans = Ls_ans, l = l_, r = r_, u = u_, d = d_;
            Now_tmp *= Del;
        }
        return Now_ans;
    }
    
    int main() {
        srand(time(0) + 19991206);
        n = read();
        for(int i = 1; i <= n; i ++) {
            int x = read(), y = read();
            A[x][y] = 1;
            Max_n = std:: max(Max_n, x), Max_m = std:: max(Max_m, y);
        }
        for(int i = 1; i <= Max_n; i ++)
            for(int j = 1; j <= Max_m; j ++)
                sum_h[i][j] = sum_h[i][j - 1] + A[i][j];
        for(int i = 1; i <= Max_m; i ++)
            for(int j = 1; j <= Max_n; j ++)
                sum_l[j][i] = sum_l[j - 1][i] + A[j][i];
        int T = 50;
        int Answer = -1;
        for(; T; T --) Answer = std:: max(Answer, MNTH());
        printf("%d", Answer);
        return 0;
    }
  • 相关阅读:
    同舟共济
    MQTT客户端
    Emgucv安装及使用
    Go生成UUID
    Go语言使用百度翻译api
    Go压缩文件
    Go语言的标准net库使用
    Go文件操作
    Go语言获取本地IP地址
    禅道使用规范
  • 原文地址:https://www.cnblogs.com/shandongs1/p/9520643.html
Copyright © 2011-2022 走看看