1. 程式人生 > >紫書——Data Mining UVA - 1591

紫書——Data Mining UVA - 1591

題目大意:

這題估計沒多少人願意做,題目太難懂了(我放棄了幾次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;
}