炸蝦碎碎念。

[Notes, GNU/Linux, Open Source, Ruby on Rails, Computer Science, Archlinux]

[Code] UPRC-1152 佈置問題

zerosea.tfcis.org:8080/JudgeOnline/showproblem?problem_id=1152

樹型依賴背包

看了學長的培訓講義才會的

#include <stdio.h>  
#include <vector>  
#include <algorithm>  
using namespace std;  

int dp[501][5001];  
int v[501], w[501];  
int n, m;  
vector<int> G[501];  
int dfs(int mom, int W)  
{  
 for (int i = 0; i < G[mom].size(); i++) {  
 int chl = G[mom][i];  
 dp[chl][W] = dp[mom][W];  
 dp[mom][W] = max(dp[mom][W], dfs(chl, W));  
 }  
 if (w[mom] > W) {  
 return 0;  
 }  
 return dp[mom][W - w[mom]] + v[mom];  
}  
int main()  
{  
 int t;  
 scanf("%d", &t);  
 while (t--) {  
 scanf("%d%d", &n, &m);  
 v[0] = w[0] = 0;  
 int dep;  
 for (int i = 1; i <= n; i++) {  
 scanf("%d%d%d", &dep, &w[i], &v[i]);  
 G[dep].push_back(i);  
 }  
 for (int i = 1; i <= m; i++) {  
 dp[0][i] = 0;  
 dp[0][i] = max(dp[0][i], dfs(0, i));  
 }  
 printf("%d\n", dp[0][m]);  
 for (int i = 0; i <= n; i++) {  
 G[i].clear();  
 }  
 }  
 return 0;  
}  

[Code] UPRC-1149 太空船(TOI初選2007pD)

http://zerosea.tfcis.org:8080/JudgeOnline/showproblem?problem_id=1149

這題最難的地方在於方向 (我是J睿捏我才會的)

  1. 起點放入queue

  2. 從queue拿出點 四周可以通行的點步數都+1

  3. 固定方向把接下來的點都放入queue 直到不能放為止
        重點是要記得紀錄步數和把點戳成黑洞

感謝jghs1328幫我debug好久..

#include <stdio.h>  

typedef struct {  
 int x;  
 int y;  
} point;  
point que[1000000];  
point s, t;  
char space[1002][1002];  
int cost[1002][1002];  
int dx[4] = {1, 0, -1, 0};  
int dy[4] = {0, 1, 0, -1};  
int front, rear;  
int main()  
{  
 int n, i, j;  
 scanf("%d\n", &n);  
 for (i = 1; i <= n; i++) {  
 for (j = 1; j <= n; j++) {  
 space[i][j] = getchar();  
 if (space[i][j] == '1') {  
 space[i][j] = 0;  
 } else if (space[i][j] == 'A') {  
 s.x = i;  
 s.y = j;  
 } else if (space[i][j] == 'B') {  
 t.x = i;  
 t.y = j;  
 }  
 }  
 getchar();  
 }  
 front = rear = 0;  
 que[rear++] = s;  
 space[s.x][s.y] = 0;  
 cost[s.x][s.y] = -1;  
 while (front < rear) {  
 point p = que[front++];  
 point n;  
 space[p.x][p.y] = 0;  
 if (p.x == t.x && p.y == t.y) {  
 break;  
 }  
 for (i = 0; i < 4; i++) {  
 n.x = p.x + dx[i];  
 n.y = p.y + dy[i];  
 if (space[n.x][n.y] == 0) {  
 continue;  
 }  
 que[rear++] = n;  
 cost[n.x][n.y] = cost[p.x][p.y] + 1;  
 space[n.x][n.y] = 0;  
 int tmp = cost[n.x][n.y];  
 n.x += dx[i];  
 n.y += dy[i];  
 while (space[n.x][n.y] != 0) {  
 que[rear++] = n;  
 cost[n.x][n.y] = tmp;  
 space[n.x][n.y] = 0;  
 n.x += dx[i];  
 n.y += dy[i];  
 }  
 }  
 }  
 printf("%d\n", cost[t.x][t.y]);  
 return 0;  
}  

[Code] TIOJ-1240 LIS but Not LIS

http://tioj.redirectme.net:8080/JudgeOnline/showproblem?problem_id=1240

先sort但記錄原順序

對於每個s[i]拿最近且比他大的點


#include <stdio.h>
#include
using namespace std;

pair<int, int> s[101];  
int main()  
{  
 int n, i;  
 scanf("%d", &n);  
 for (i = 0; i < n; i++) {  
 scanf("%d", &(s[i].first));  
 s[i].second = i;  
 }  
 sort(s, s + n);  
 int count = 0;  
 bool update;  
 pair<int, int> last;  
 do {  
 update = false;  
 for (i = 0; i < n; i++) {  
 if (s[i].first >= 0 && (!update ||  
 s[i].second > last.second && s[i].first > last.first)) {  
 last = s[i];  
 s[i].first = -1;  
 update = true;  
 }  
 }  
 if (update) {  
 count++;  
 }  
 } while (update);  
 printf("%d\n", count);  
 return 0;  
}  

[Code] TIOJ-1509 地道問題 (TOI初選2008pD)

http://tioj.redirectme.net:8080/JudgeOnline/showproblem?problem_id=1509

如果TIOJ又掛了的話= =
http://zerosea.tfcis.org:8080/JudgeOnline/showproblem?problem_id=1128

做第一次dijkstra -> 把邊反過來 -> 再做一次

P.S. 冏我都被J睿捏好玩的 不捏我都想不到…

#include <stdio.h>  
#include <vector>  
#include <queue>  
#include <algorithm>  
#include <string.h>  
#define INF 1000000001  
using namespace std;  

typedef struct {  
 int to;  
 int cost;  
} edge;  
typedef pair<int, int> P;  
vector<edge> G[1000001];  
vector<edge> R[1000001];  
long long d[1000001];  
bool visited[1000001];  
priority_queue<P, vector<P>, greater<P> > que;  
int main()  
{  
 int s, t, c, V, E;  
 long long sum;  
 while (~scanf("%d%d", &V, &E)) {  
 sum = 0;  
 fill(d, d + V + 1, INF);  
 memset(visited, false, sizeof(visited));  
 edge e;  
 for (int i = 1; i <= V; i++) {  
 G[i].clear();  
 R[i].clear();  
 }  
 for (int i = 0; i < E; i++) {  
 scanf("%d%d%d", &s, &t, &c);  
 e.to = t;  
 e.cost = c;  
 G[s].push_back(e);  
 e.to = s;  
 R[t].push_back(e);  
 }  
 d[1] = 0;  
 que.push(P(0, 1));  
 while (que.size()) {  
 P p;  
 while (que.size()) {  
 p = que.top();  
 que.pop();  
 if (!visited[p.second]) {  
 break;  
 }  
 }  
 visited[p.second] = true;  
 int v = p.second;  
 if (d[v] < p.first) {  
 continue;  
 }  
 for (int i = 0; i < G[v].size(); i++) {  
 edge e = G[v][i];  
 if (d[v] + e.cost < d[e.to]) {  
 d[e.to] = d[v] + e.cost;  
 que.push(P(d[e.to], e.to));  
 }  
 }  
 }  
 bool jump = false;  
 for (int i = 1; i <= V; i++) {  
 if (d[i] == INF) {  
 jump = true;  
 break;  
 }  
 sum += d[i];  
 }  
 if (jump) {  
 puts("0");  
 continue;  
 }  
 que.push(P(0, 1));  
 fill(d, d + V + 1, INF);  
 memset(visited, false, sizeof(visited));  
 d[1] = 0;  
 while (que.size()) {  
 P p;  
 while (que.size()) {  
 p = que.top();  
 que.pop();  
 if (!visited[p.second]) {  
 break;  
 }  
 }  
 visited[p.second] = true;  
 int v = p.second;  
 if (d[v] < p.first) {  
 continue;  
 }  
 for (int i = 0; i < R[v].size(); i++) {  
 edge e = R[v][i];  
 if (d[v] + e.cost < d[e.to]) {  
 d[e.to] = d[v] + e.cost;  
 que.push(P(d[e.to], e.to));  
 }  
 }  
 }  
 for (int i = 1; i <= V; i++) {  
 if (d[i] == INF) {  
 jump = true;  
 break;  
 }  
 sum += d[i];  
 }  
 if (jump) {  
 puts("0");  
 continue;  
 }  
 printf("%I64d\n", sum);  
 }  
 return 0;  
}  

[Code] Uva-11069 a Graph Problem

http://uva.onlinejudge.org/external/110/11069.html
我太急了 一下子沒想出來就看別人code
這其實很好想啊…
我好廢啊= =
因為不能走到相鄰的點
中間也不能有地方能插入合法的點
所以只有兩種狀況
走到第n + 2個點
或是第n + 3個點

#include <stdio.h>

int dp[77];  
int main()  
{  
 int i, n;  
 dp[1] = 1;  
 dp[2] = 2;  
 dp[3] = 2;  
 while (scanf("%d", &n) != EOF) {  
 if (dp[n]) {  
 printf("%d\n", dp[n]);  
 continue;  
 }  
 for (i = 4; i <= n; i++) {  
 dp[i] = dp[i - 2] + dp[i - 3];  
 }  
 printf("%d\n", dp[n]);  
 }  
 return 0;  
}  

[Code] Uva-10583 Ubiquitous Religions

http://uva.onlinejudge.org/external/105/10583.html
很簡單的Disjoint Set
最後輸出Case n: ans
C是大寫= = 害我WA了兩次
另外Uva真的是ANSI C..
註解只能用
/* This is a comment. */不能 用
// Not allowed in ANSI C害我吃了一次CE…

#include <stdio.h>

int group;  
int set[50001];  
int rank[50001];  
void set_init(int n)  
{  
 int i;  
 for (i = 1; i <= n; i++) {  
 set[i] = i;  
 rank[i] = 1;  
 }  
 return ;  
}  
int find(int x)  
{  
 if (set[x] == x) {  
 return x;  
 } else {  
 return set[x] = find(set[x]);  
 }  
}  
void unite(int a, int b)  
{  
 a = find(a);  
 b = find(b);  
 if (a == b) {  
 return ;  
 }  
 group--;  
 if (rank[a] < rank[b]) {  
 set[a] = b;  
 } else {  
 set[b] = a;  
 if (rank[a] == rank[b]) {  
 rank[a]++;  
 }  
 }  
}  
int main()  
{  
 int n, m, i, j, count = 0;  
 while (scanf("%d%d", &n, &m) != EOF && n && m) {  
 count++;  
 group = n;  
 set_init(n);  
 while (m--) {  
 scanf("%d%d", &i, &j);  
 unite(i, j);  
 }  
 printf("Case %d: %d\n", count, group);  
 }  
 return 0;  
}  

[Code] TIOJ-1717 專案時程(TOI2010初選pB)

http://tioj.redirectme.net:8080/JudgeOnline/showproblem?problem_id=1717

戳入度(in-degree)為零的點下去DFS再取最大值

#include <stdio.h>  
#include <string.h>  
#include <vector>  
#include <algorithm>  
using namespace std;  

int cost[1001];  
long long dp[1001];  
int in_deg[1001];  
vector<int> G[1001];  
long long dfs(int v)  
{  
 if (dp[v]) {  
 return dp[v];  
 }  
 long long res = 0;  
 for (int i = 0; i < G[v].size(); i++) {  
 res = max(dfs(G[v][i]), res);  
 }  
 return dp[v] = res + cost[v];  
}  
int main()  
{  
 int t, n, k, to;  
 scanf("%d", &t);  
 while (t--) {  
 scanf("%d", &n);  
 memset(dp, 0, sizeof(dp));  
 memset(in_deg, 0, sizeof(in_deg));  
 for (int i = 1; i <= n; i++) {  
 scanf("%d%d", &cost[i], &k);  
 while (k--) {  
 scanf("%d", &to);  
 in_deg[to]++;  
 G[i].push_back(to);  
 }  
 }  
 long long ac = 0;  
 for (int i = 1; i <= n; i++) {  
 if (in_deg[i] == 0) {  
 ac = max(dfs(i), ac);  
 }  
 }  
 printf("%I64d\n", ac);  
 for (int i = 1; i <= n; i++) {  
 G[i].clear();  
 }  
 }  
 return 0;  
}  

aod250上裝Debian+LXDE遇到的問題與解決

在自己的Acer Aspire One d250(aod250)上裝Debian sid

遇到了不少問題

以下是找到的解決方案

  1. 無線網卡(Broadcom BCM4312)

Debian的套件庫裡已有它的驅動程式

sudo aptitude install firmware-b43-lpphy-installer wpasupplicant  
sudo modprobe b43  

在 /etc/network/interfaces 裡加上:

auto wlan0 inet dhcp  
wpa-ssid home #(你ssid的名字)  
wpa-psk ********** #(你的WPA密碼)  

然後

sudo chmod 0600 /etc/network/interfaces #(保護你的wifi密碼)  
sudo ifconfig wlan0 up  

2.在LXDE中 觸控板不能像在ubuntu/windows 上一樣 輕輕在板子上點 就可以選擇

sudo aptitude install gsynaptics

在/etc/xdg/lxsession/LXDE/autostart 前面加上

synclient VertEdgeScroll=1  
synclient HorizEdgeScroll=1  
synclient TapButton1=1  

然後登出再登入 就可以了

3.沒有聲音

sudo aptitude install gnome-alsamixer  
gnome alsa-mixer   

把 PCM 和 Speaker 調到最大 就解決了

工具列沒有音量調整按鈕?

在工作列上按右鍵 點 ”設定工作列 (panel settings)”

在工作列元件裡增加 『音量控制』

參考資料

http://wiki.debian.org/bcm43xx

http://wiki.debian.org/WiFi/HowToUse

http://solutionsandtips.blogspot.com/2010/07/enable-touchpad-tapping-scrolling-in.html

[GNU/Linux]在debian用sudo

最近裝了debian
習慣在了terminal下用sudo

root@debian~# visudo  
#在最後一行加上  
joshua ALL=(ALL) NOPASSWD:ALL  
#按ctrl+o寫入再按ctrl+x離開  

從今以後
不僅有sudo可以用
而且還不用密碼!

參考資料
鳥哥的linux私房菜