USACO Postal Vans 解題報告

2021-06-26 16:50:47 字數 2884 閱讀 1478

這道題我是用偷懶的方法做的。在topcoder論壇上面看到大名鼎鼎的msg555也是用的這種方法,於是我就放心了。首先,用dfs跑n比較小的情況,可以跑到n=10,如果你足夠耐心的話,也可以得到更多結果。於是就有了下面的結果,對n=1~11:int arr = ; 在這之後就是找規律了。我是給系統發郵件)和**都可以得到生成函式,後者還可以以極短的時間算出來後續的序列(很好奇是如何做到的,還是高精度運算)。由於數學功底已經不如之前了,不知道如何從生成函式匯出遞推公式。但知道有遞推公式的存在,找到規律還是比較簡單的。

我們有:a[n] = 2 * a[n - 1] + 2 * a[n - 2] - 2 * a[n - 3] + a[n - 4]

之後就是如何根據這個遞推式匯出結果,及超過int的範圍怎麼辦(觀察增長速度,突破32位int是很快的事情)。

我用的是最*****的方法,寫了個1000位的加法和減法,然後把乘法當做多次加法(或減法)。於是就有了下面的解法:

user: chen chen [thestor1]

task: vans

lang: c++

compiling...

compile: ok

executing...

test 1: test ok [0.008 secs, 3504 kb]

test 2: test ok [0.008 secs, 3504 kb]

test 3: test ok [0.003 secs, 3504 kb]

test 4: test ok [0.008 secs, 3504 kb]

test 5: test ok [0.005 secs, 3504 kb]

test 6: test ok [0.008 secs, 3504 kb]

test 7: test ok [0.005 secs, 3504 kb]

test 8: test ok [0.016 secs, 3504 kb]

test 9: test ok [0.032 secs, 3504 kb]

test 10: test ok [0.043 secs, 3504 kb]

test 11: test ok [0.057 secs, 3504 kb]

all tests ok.

/* 

id: thestor1

lang: c++

task: vans

*/#include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include using namespace std;

const int maxn = 1000;

int n;

int dx = , dy = ;

bool isin(int r, int c)

vector> neighbors(int r, int c)

} return nbs;

}void dfs(vector> &visited, int r, int c, int cnt, int &total)

return;

} vector> nbs = neighbors(r, c);

int nr, nc;

for (int i = 0; i < nbs.size(); ++i) }

}void zero(std::vector&num)

}void assign(std::vector&lhs, std::vector&rhs)

}void add(std::vector&lhs, std::vector&rhs)

assert(carry == 0);

}void sub(std::vector&lhs, std::vector&rhs)

else

}assert (borrow == 0);

}void print(const std::vector&lhs)

for (int i = begin; i < lhs.size(); ++i)

cout << endl;

}int main()

; ofstream fout("vans.out");

fout << arr[n - 1] << endl;

fout.close();

return 0;

} // vector> visited(4, vector(n, false));

// int total = 0;

// dfs(visited, 0, 0, 0, total);

// a[n] = 2 * a[n - 1] + 2 * a[n - 2] - 2 * a[n - 3] + a[n - 4]

vector> a(5, vector(maxn, 0));

// a[0]

a[1][maxn - 1] = 2;

a[2][maxn - 1] = 4;

a[3][maxn - 2] = 1;

a[3][maxn - 1] = 2;

int a0 = 0, a1 = 1, a2 = 2, a3 = 3;

for (int i = 4; i < n; ++i)

ofstream fout("vans.out");

int begin = 0;

while (begin < maxn && a[4][begin] == 0)

for (int i = begin; i < a[4].size(); ++i)

fout << endl;

fout.close();

return 0;

}

USACO Hamming Codes 解題報告

資料小,暴力搜尋可以搞定。但是推薦使用dfs,每個節點 數 有取與不取兩個分支。注意 0是必須出現的。證明如下 最終得到的結果序列中,0是必須出現的,證明如下 如果存在另乙個滿足要求的結果序列s 其最小值為a1 n 0,那麼序列s s n 是滿足條件的最小解,且首元素為0 id xpli1 prog...

USACO Closed Fences 解題報告

幾何題看著就很有畏懼感。這裡用的是最 的演算法,時間複雜度應該在n 2。還沒看別人的解題報告,不過我猜nlogn的解法是有的。比如判斷乙個fence是不是valid的時候,這裡將所有的線段兩兩比較,看是否相交。但是有個叫line sweep的演算法,可以在nlogn的時間複雜度內完成。既然accep...

Wiggle Subsequence解題報告

這道題和最長子序列,divisible subset題目類似,都可以用o n2 的時間複雜度完成。可以想象,對於第i個數,dp i dp j 1,當且僅當dp j 1 dp i 而且nums j 和nums i 的差值和j所處位置的差值符號相反。所以,如下 class solution if dp ...