HDU4495 Rectangle

求组成的等腰三角形面积最大值。

对此题的总结:暴力出奇迹

组成的三角形放置方式一共只有4种,用ans表示目前已知的最长三角形的边长,从上到下,从左到右枚举顶点,再枚举边长,一个重要剪枝是枚举边长l时先判断l = ans时的边能不能对称。

最终暴力只要200多ms,而时间限制为10s

 #include<cstdio>

#include<iostream>
#include<cstdlib>
#include<cstring>
#include<string>
#include<algorithm>
#include<map>
#include<queue>
#include<vector>
#include<cmath>
#include<utility>
using namespace std;
typedef long long LL;
const int N = 508, INF = 0x3F3F3F3F;
#define MS(a, num) memset(a, num, sizeof(a))
#define PB(A) push_back(A)
#define FOR(i, n) for(int i = 0; i < n; i++)
char g[N][N];
int n, m;
int ans  = 0;

bool judge(int x1, int y1, int x2, int y2){
    while(y1 < y2){
        if(g[x1][y1] != g[x2][y2]){
            return false;
        }
        x1--;
        x2++;
        y1++;
        y2--;
    }
    return true;
}


bool judge2(int x1, int y1, int x2, int y2){
    while(x1 < x2){
        if(g[x1][y1] != g[x2][y2]){
            return false;
        }
        x1++;
        x2--;
        y1++;
        y2--;
    }
    return true;
}


void solve1(){
    for(int i = 0 ;i < n; i++){
        for(int j = 0; j < m; j++){
            if(i + ans -1 < n && j + ans - 1 < m){

            if(!judge(i + ans - 1, j, i, j + ans - 1)){
                    continue;
                }
            for(int l =2 ; i + l -1 < n && j + l - 1 < m; l++){
                if(!judge(i + l - 1, j, i, j + l - 1)){
                    break;
                }
                ans = max(ans , l);
            }
            }
        }
    }
}


void solve2(){
    for(int i = 0 ;i < n; i++){
        for(int j = 0; j < m; j++){

            if(j - ans + 1 >= 0&& i + ans - 1 < n){

            if(!judge2(i, j - ans + 1, i + ans - 1, j )){
                    continue;
                }

            for(int l =2; j - l + 1 >= 0&& i + l - 1 < n; l++){
                if(!judge2(i, j - l + 1, i + l - 1, j )){
                    break;
                }
                ans = max(ans , l);
            }
        }
        }
    }
}

void solve3(){
    for(int i = 0 ;i < n; i++){
        for(int j = 0; j < m; j++){
            if(i - ans + 1 >= 0&& j + ans - 1 < m){

            if(!judge2(i - ans + 1, j, i , j + ans - 1)){
                    continue;
                }
            for(int l = 2; i - l + 1 >= 0&& j + l - 1 < m; l++){
                if(!judge2(i - l + 1, j, i , j + l - 1)){
                    break;
                }
                ans = max(ans , l);
            }
            }
        }
    }
}

void solve4(){
    for(int i = 0 ;i < n; i++){
        for(int j = 0; j < m; j++){
            if(j - ans + 1 >= 0&& i - ans + 1 >= 0){

            if(!judge(i, j - ans + 1, i - ans + 1 , j)){
                    continue;
                }
            for(int l = 2; j - l + 1 >= 0&& i - l + 1 >= 0; l++){
                if(!judge(i, j - l + 1, i - l + 1 , j)){
                    break;
                }
                ans = max(ans , l);
            }
            }
        }
    }
}

int main(){
    int t;
    cin>>t;
    while(t--){
        cin>>n>>m;
        for(int i= 0 ; i< n; i++){
            scanf("%s", g[i]);
        }
        ans = 1;
        int mini = min(n ,m);
        solve1();
        if(ans != mini){
            solve2();
        }
        if(ans != mini){
            solve2();
        }

        if(ans != mini){
            solve3();
        }
        if(ans != mini){
            solve4();
        }

        cout<<ans * (ans + 1)/2<<' ';
    }

    return 0;
}
原文地址:https://www.cnblogs.com/IMGavin/p/5698847.html