題目大意:給你一組數字,從數字裡選擇a,b,c,d四個數字(四個數字各不相同),滿足a+b+c=d;
題目思路:如果列舉a,b,c得到a+b+c然後再匹配d的話,複雜度為n^3,這樣就會超時,但是如果分別列舉a+b與d-c的話這樣時間複雜度就會降到n^2,再進行匹配,還可以進行再進行排序,然後採用二分相互匹配。
坑點:d的值盡量的大,也就是說你匹配時,要不斷維護d的值,保證d最大;a,b,c,d相互不重合,所以你必須在記錄a+b與d+c時同時記錄他們的座標位置(結構體)
教訓:在判斷重複時忽略了ab cd之間的重複。
**:
#include#include#includeusing namespace std;
const int maxn=1e6+10;
const int inf=2e9+7;
struct nodea[maxn],b[maxn];
bool cmp(node p,node q)
if(pos==inf) continue;
for(int j=pos;jans) ans=c[b[j].x];}}
if(ans!=-inf) printf("%d\n",ans);
else printf("no solution\n");
}}
POJ2549 Sumsets 折半列舉
題目大意是,乙個集合中有n個元素,找出最大的s,滿足條件a b c s,並且這四個數都屬於該集合,n不超過1000.如果直接列舉o n 4 顯然複雜度太高,將等式轉化一下a b s c,此時分別對左右兩邊的值進行列舉,這一步複雜度為o n 2 接著就用二分法查詢滿足該等式的最大s值,複雜度為o n ...
POJ 2549 Sumsets 折半列舉
題意 在集合s中有n個數,找到最大的d,且d滿足於集合內a b c d。題解 我們把找a b c d化為找 a b d c。設c為a,b,c中最大的元素。注意d不一定比c大,d c可以為負數。這樣我們列舉d,c,利用二分的思想查詢a,b。如下 include include include defi...
poj 2549 Sumsets 折半列舉
思路 暴力會超時,就得找個時間小的方法,先變形 a b d c 這樣只列舉d c,用相向搜尋是否存在兩個數a b d c.題中有正有負 所以d也可能是負數 include include include define inf 0x3f3f3f using namespace std int main...