紫書——Data Mining UVA - 1591
阿新 • • 發佈:2018-11-09
題目大意:
這題估計沒多少人願意做,題目太難懂了(我放棄了幾次orz)
先了解題意:
首先P(i)和Q(i)我們要將他了解為偏移量,就是離開始陣列p【0】啊等等的距離,而他們每個位元組就是Sp和Sq;
這就很好理解第一二條公式了
Pofs(i) = SP · i 就是P【i】離P【0】的距離,也可以理解為陣列P有i個元素的大小
Qofs(i) = SQ · i. 這個和上面同理
而
Pofs(i + 1) = Pofs(i) + SP
Pofs(i − 1) = Pofs(i) − SP
這兩條公式也很容易從上面兩條推匯出來,多一個就是多sp嘛
又因為
i = Pofs(i)/SP =》 Qofs(i) = Pofs(i)/SP · SQ
上面的公式其實沒用,但是要將他理解為通過 P 定位出 Q的資料 (重點!!!!)
但是由於除法和乘法太慢了,所以博士用空間轉換為時間,得出下面公式
Qofs’(i) = (Pofs(i) + Pofs(i)<<A) >> B
這條公式也是通過P定位Q的資料位置,好比對映位置一樣,學過彙編都應該知道就像中斷向量表一樣,最後加上一個Q的大小就等於全部Q的大小了
但是現在Q已經不是連續的了,中間可能有些位置是沒有資料的,所以我們要找最小的陣列大小K;
K相同就找A小的,A相同就找B小的,一分析就知道列舉A、B就行了
而由於N*Sq最大範圍為 2^30 (不超過int),所以我們可以將A、B分別列舉到35
#include <bits/stdc++.h> using namespace std; typedef long long ll; const int inf = 0x3f3f3f3f; int main() { ll n,p,q; while(scanf("%lld%lld%lld",&n,&p,&q) == 3) { ll k = (ll)inf*3; int a,b; for(int i = 0; i < 35; i++) { for(int j = 0; j < 35; j++) { ll tmp = (((n-1)*p + ((n-1)*p<<i))>>j) + q; if(tmp >= n*q && k > tmp) { k = tmp; a = i; b = j; } } } printf("%lld %d %d\n",k,a,b); } return 0; }