POJ3274 牛的屬性 HASH ACM

2022-01-22 05:46:44 字數 1955 閱讀 4779

原題:poj3274

參考:進擊的阿俊

已知有n頭牛,用乙個k位二進位制數ak,ak-1,...,a1表示一頭牛具有的特徵,ai=1表示具有特徵i。現給定按順序排列的n頭牛的k位特徵值,稱某個連續範圍內「特徵平衡」,假如在這個範圍內,擁有各個特徵的牛的數量都相等。求最大「特徵平衡」連續範圍。

分析:用sum[i][j]( 1<=i<=n, 1<=k<=j)表示1到第i頭牛中具有特徵j的牛的數量。問題轉化為求解滿足sum[i][l] - sum[j][l] = sum[i][1] - sum[j][1](l = 1,2,..,k)的最大i - j的值。很容易想到最簡單的方法,通過令d = n to 1,判斷是否存在i,使得sum[i + d][j] - sum[i][j] = sum[i + d][1] - sum[i][j],時間複雜度為o(n*n*k)。由於n的最大值能達到100000,必須選擇乙個更加優化的方法。

1)容易驗證,sum[i][l] - sum[j][l] = sum[i][1] - sum[j][1] ( l = 1,2,..,k ) 等價於sum[i][l] - sum[i][1] = sum[j][l] - sum[j][1] ( l = 1,2,...k )。因此令d[i][j] =  sum[i][j] - sum[i][1] ,問題就轉化為求解使得d[i][j] = d[i + size][j]的最大size。

2)為進一步簡化演算法,對於任意 1<= i <=n, 令sig[i] = (d[i][1] + d[i][2] + ... +d[i][k] ) % m (m為乙個較大的質數)。這樣,若對於i和j, sig[i] != sig[j],那麼必定不會滿足d[i] = d[j],就無需再對它進行驗證;若滿足sig[i] = sig[j],才需要進一步確定是否有d[i] = d[j]。

3)用h[k] (1 <= k <= m,m為以上取模運算的素數)記錄滿足sig[i] = k的i值。通過令 i = 1 to n,以此更新h[sig[i]]和largest,即可得到結果。

樣例輸入

7 376

7214

2

樣例輸出

int d[maxn][maxk]; //d 和 sig輔助計算雜湊值

int s, size;

const int prime = 49117;

int sig[maxn];

int largest;

vector h[prime]; //雜湊表

void search(int i, int t)//0 1 \ 2 2 \ 2 3 \ 3 4 \

}if (flag)

}h[i].push_back(t);

//printf("i:%d push back t:%d\n",i,t);

}int findlargest()

return largest;

}void init()

//printf("%d\n",sig[i]);

/*for (j = 0; j < k; j++)

*/sig[i] = abs(sig[i]) % prime;

}}int main()

}init();

findlargest();

printf("%d\n", largest);

//}return 0;

}

poj3274陣列的雜湊

poj3274 這道題做得坎坷啊,剛開始沒注意看hint,硬生生地一直看不懂題意。好不容易看懂題目後也沒什麼思路。參看別人的思路後了下面巨醜無比的 懶得改了。這道理給我的收穫就是,有些題目不能急,是需要先用數學推理一些等價關係後才會知道該用什麼演算法的。思路 sum i j 前i頭牛的feature...

poj 3274 數的雜湊

據說這題很經典噢 開始的分析也經典。題目的分析我就不多說了,具體可以參考 一看就很清楚了 感謝這位博主 但他用的hash函式我暫時是不能理解,說以沒用它的方法。自己寫了個簡單的hash方法,似乎還挺湊效,然後再處理衝突。一開始時,我是先hash一邊,然後再來個for迴圈來判斷每個hash值.tle。...

資料結構之雜湊(poj3274)

寒假集訓的時候學習了一下雜湊,但是一直沒有練習,這幾天找了幾道雜湊的題目,發現忘的差不多了。做了幾道題之後發現雜湊真的是乙個很高效的資料結構,體驗到了資料結構的強大。構建雜湊表示為了能夠更高效率的查詢,還記得小學的時候查字典嗎?其實雜湊就相當於那樣乙個東西,他把資料按照一定的雜湊函式生成乙個鍵值,然...