問題のP3117の解決策[[USACO15JAN]矩形牛牛四角形]

でも何暴力、彼は貪欲な香をしませんでした

あなたはこの質問を分離したい場合は実際には、我々は3例を議論する必要があります:(そのような計画を発行していないので、手だけを再生することができます

1)

5。

4。

3。H。

2。G。

1。H。

0 1 2 3 4 5

この場合には、次の2つのHが確かに設定されていない(それらはGを持っているので)

2)

5。G。

4。H。

3。H。

2。H。

1。G。

0 1 2 3 4 5

H / Gの下にあるため、この場合には、上記のすべて、すべてHを取ることができます

3)

5。H。

4。G。

3。H。

2。H

1。H。

012345この場合、Hは、以下のすべてを取ることではなくても(Gによってブロック)上記でき

したがって、我々は(メソッドのコメントを判断参照)リストにこれらの3例を判断する必要があります

pp find_pair(int aa, int bb){ int mini = 1e8,maxi = 0; int low = aa, high = bb; while(cow[low-1].x==cow[aa].x) {low--;if (low==0)break;} while(cow[high-1].x==cow[bb].x) {high++; if (high == 0) break;} //这是一个很重要的判断: //因为我们在排序的时候有可能遇到x相等的点,这个点并不会被搜索,但是这个点仍然需要判断。在这个时候就需要往前和后搜索x相等的点 for (int i=low;i<=high;i++){ if (cow[i].id=='G'){ if (cow[i].y>max(cow[aa].y,cow[bb].y)) mini = min(mini,cow[i].y); else if (cow[i].y<min(cow[aa].y,cow[bb].y)) maxi = max(maxi,cow[i].y); else posible = false; } }//如果这两个点中间有G就进行以下判断: //1.如果这个G的y坐标在这两个点的y之上,那么我们将最高值更新 //2.如果这个G的坐标在y之下,我们将最小值之下,我们更新最小值 //3.如果这个G在两个坐标中间,那么这两个点必然不可能选(因为无论怎么样连最后G都会在这个范围里) return make_pair(mini,maxi); }

質問があるので、どのようにそれの真ん中に2つのH Gの保証を見つけるには?

私は、あなたを求めるソートだけで罰金を追加する必要があります

*注:Gを探しているとき、我々はxはGとHの座標が彼の範囲内ではないかもしれない時間の一種で、同じであることを覚えておく必要があります。それをどのように行うには?

私はあなたを依頼する必要があり、カットに等しいx座標が/彼が等しくない追加しました

while(cow[low-1].x==cow[aa].x) {low--;if (low==0)break;} while(cow[high-1].x==cow[bb].x) {high++; if (high == 0) break;}

完成Gを見た後、我々は2点間のすべてのHを判断します。

Hは、垂直G Yの範囲内であれば、我々は、最大/最小値を更新します。(高い更新に相当)

pp in_range(int aa, int bb, pp bo){ int maxi = 0,mini = 1e8; for (int i=aa;i<=bb;i++){ if (cow[i].id!='G'){ if (between(bo,cow[i].y)){ maxi = max(maxi,cow[i].y); mini = min(mini,cow[i].y); temp++; } } }//现在已经找出了在这个点上面最低的G点和下面最高的G点 //我们在这个范围里面搜索所以的H,更新最高点和最低点(前提是要在G点的范围内) return make_pair(maxi,mini); }

仕上がりを見た後どうしますか?

私はああエリアを見つけ、もちろん、あなたが聞いています

底面積= 高い=(X2-X1) ABS(Y1-Y2)[ソートなど、X2必見> = X1そう]

if (temp){
        if(temp>breed){
          //如果H的数量大于之前的,直接更新
          breed = temp;
          ans = abs(res.first-res.second)*abs(cow[j].x-cow[i].x); }else if (temp==breed) ans = min(ans,abs(res.first-res.second)*abs(cow[j].x-cow[i].x));//否则更新面积(底『x的差』乘高『最高y值和最低y值的差』 }

全く記憶が決定されていないため、このプログラムは、実際には十分なスペース500(800-KBは、それが十分に小さいなければならない)であります

完全なコードは次のとおりです。

#include <iostream>
#include <algorithm> #include <math.h> #include <stdio.h> using namespace std; #define pp pair<int,int> struct node{ int x,y; char id; }cow[100005]; int tot = 0, temp = 0; int a,b,c; char d; void add(int aa, int bb, char cc){ cow[++tot].x = aa; cow[tot].y = bb; cow[tot].id = cc; } bool sorted(node aa, node bb){ return aa.x<bb.x; } bool between(pp aa,int b){ return aa.first>b && aa.second<b; }//这个是表示一个数是否在两个数直接 bool posible = true; pp find_pair(int aa, int bb){ int mini = 1e8,maxi = 0; int low = aa, high = bb; while(cow[low-1].x==cow[aa].x) {low--;if (low==0)break;} while(cow[high-1].x==cow[bb].x) {high++; if (high == 0) break;} //这是一个很重要的判断: //因为我们在排序的时候有可能遇到x相等的点,这个点并不会被搜索,但是这个点仍然需要判断。在这个时候就需要往前和后搜索x相等的点 for (int i=low;i<=high;i++){ if (cow[i].id=='G'){ if (cow[i].y>max(cow[aa].y,cow[bb].y)) mini = min(mini,cow[i].y); else if (cow[i].y<min(cow[aa].y,cow[bb].y)) maxi = max(maxi,cow[i].y); else posible = false; } }//如果这两个点中间有G就进行以下判断: //1.如果这个G的y坐标在这两个点的y之上,那么我们将最高值更新 //2.如果这个G的坐标在y之下,我们将最小值之下,我们更新最小值 //3.如果这个G在两个坐标中间,那么这两个点必然不可能选(因为无论怎么样连最后G都会在这个范围里) return make_pair(mini,maxi); } pp in_range(int aa, int bb, pp bo){ int maxi = 0,mini = 1e8; for (int i=aa;i<=bb;i++){ bool update = true; while(update){ if (cow[i].id!='G'){ if (between(bo,cow[i].y)){ maxi = max(maxi,cow[i].y); mini = min(mini,cow[i].y); temp++; } } } }//现在已经找出了在这个点上面最低的G点和下面最高的G点 //我们在这个范围里面搜索所以的H,更新最高点和最低点(前提是要在G点的范围内) return make_pair(maxi,mini); } int main(){ ios::sync_with_stdio(0); cin >> a; for (int i=0;i<a;i++){ cin >> b >> c >> d; add(b,c,d); } int ans = 0, breed = 1; sort(cow+1,cow+tot+1,sorted); //以上不解释 for (int i=1;i<=a;i++){ for (int j=i+breed;j<=a;j++){ if (cow[i].id=='G'||cow[j].id == 'G') continue;//如果两个点中有G就不需要判断 posible = true; temp = 0; pp bounds = find_pair(i,j);//先找G的范围 if (!posible) continue; pp res = in_range(i,j,bounds);//再找H的范围 if (temp){ if(temp>breed){ //如果H的数量大于之前的,直接更新 breed = temp; ans = abs(res.first-res.second)*abs(cow[j].x-cow[i].x); }else if (temp==breed) ans = min(ans,abs(res.first-res.second)*abs(cow[j].x-cow[i].x));//否则更新面积(底『x的差』乘高『最高y值和最低y值的差』 } } } cout << breed << endl << ans; } 

あなたは、私がカウントハエを失った、任意のは、あなたをコピーし、コピー

おすすめ

転載: www.cnblogs.com/DannyXu/p/11980596.html