USACO 2.3 分析
2011-02-13 13:55
253 查看
题目一:The Longest Prefix
题目大意:给出一组可以去匹配的字符串,求在给定的字符串中最长可以匹配出的前缀有多长?
算法1:DP
效率:O(200,000*200*10) (实际远远不到)
对于每个位置,去枚举每个字符串,在除去这个串之后的前面的串可以匹配的情况下判断对应的位时候可以匹配,只要有一个可以匹配该位就可以匹配。如果连续遇到不可匹配的数目大于最大可以匹配的长度的时候,就可以退出了。
小经验:用scanf("%c", c)读字符不能跳过回车符和空格
测试时间:
Test 1: TEST OK [0.000 secs, 3276 KB]
Test 2: TEST OK [0.000 secs, 3276 KB]
Test 3: TEST OK [0.011 secs, 3276 KB]
Test 4: TEST OK [0.022 secs, 3276 KB]
Test 5: TEST OK [0.022 secs, 3276 KB]
Test 6: TEST OK [0.054 secs, 3276 KB]
算法2:Trie(单词查找树)(这种算法好像当时一下子就写出来了,但到现在才知道它的名字)
效率:O(200,000)
题目二:Cow Pedigrees
题目大意:求N个结点高度为K的树的种数
算法:DP
效率:O(NK)
s[i][j] = s[left][h]*s[right][j-1] + s[left][j-1]*s[right][h] + s[left][j-1]*s[right][j-1] 1<=h<=j-2,1<=left, right <i and left + right + 1 = i
优化:满足这种条件的树的节点数一定为奇数;最大高度不会超过(N+1)/2;
题目三:Zero Sum
算法:DFS
注意:算的时候要从左向右算,从右向左算稍麻烦;
题目四:Money Systems
算法:DP 背包
小知识:INT64在DEV-C++的g++编译器中printf("%I64d",n),而在GNU中要写成printf("%lld",n)
题目五:Controlling Company
算法:DFS/BFS
关键是要理解题目中的规则
(1)不解释(2)不解释(3)你的控制的公司称为子公司,则子公司的子公司仍然是你的公司,也受你的管辖
这道题实质是图论的题目,可以用邻接表来存贮,哪种搜索随便了。第一条规则在搜索时意味着你先把自己作为本体去拓展
题目大意:给出一组可以去匹配的字符串,求在给定的字符串中最长可以匹配出的前缀有多长?
算法1:DP
效率:O(200,000*200*10) (实际远远不到)
对于每个位置,去枚举每个字符串,在除去这个串之后的前面的串可以匹配的情况下判断对应的位时候可以匹配,只要有一个可以匹配该位就可以匹配。如果连续遇到不可匹配的数目大于最大可以匹配的长度的时候,就可以退出了。
小经验:用scanf("%c", c)读字符不能跳过回车符和空格
#include <stdio.h> #include <string.h> #include <string> #include <iostream> using namespace std; const int maxlen = 200000+2; bool h[maxlen]; char ch[maxlen]; char s[11]; char pri[201][11]; bool check(int nowpos, int i) { if (strlen(pri[i]) > nowpos || !h[nowpos-strlen(pri[i])]) return false; for (int k = 0, j = nowpos-strlen(pri[i])+1; k < strlen(pri[i]); k++, j++) if (pri[i][k] != ch[j]) return false; return true; } void print(int tot_pri) { for (int i = 0; i < tot_pri; i++) printf("%s/n", pri[i]); } int main(){ freopen("prefix.in", "r", stdin); freopen("prefix.out", "w", stdout); int tot_pri = 0, maxs = 0;//maxs record the longest length of the pri while (true) { scanf("%s", s); if (s[0] == '.') break; memcpy(pri[tot_pri], s, sizeof(s)); tot_pri++; if (strlen(s) > maxs) maxs = strlen(s); } //print(tot_pri); int len = 0, maxmiss = 0, max = 0;//maxmiss record the longest length which can't compare char c; memset(h,0,sizeof(h)); h[0] = 1; c = getchar(); while (scanf("%c", &c) == 1) {//read success if (c == '/n') continue; len++; ch[len] = c; bool flag = false; for (int i = 0; i < tot_pri && !flag; i++) flag = check(len, i); if (!flag) maxmiss++; else { maxmiss = 0;max = len;} if (maxmiss > maxs) break; h[len] = flag; } printf("%d/n", max); return 0; }
测试时间:
Test 1: TEST OK [0.000 secs, 3276 KB]
Test 2: TEST OK [0.000 secs, 3276 KB]
Test 3: TEST OK [0.011 secs, 3276 KB]
Test 4: TEST OK [0.022 secs, 3276 KB]
Test 5: TEST OK [0.022 secs, 3276 KB]
Test 6: TEST OK [0.054 secs, 3276 KB]
算法2:Trie(单词查找树)(这种算法好像当时一下子就写出来了,但到现在才知道它的名字)
效率:O(200,000)
题目二:Cow Pedigrees
题目大意:求N个结点高度为K的树的种数
算法:DP
效率:O(NK)
s[i][j] = s[left][h]*s[right][j-1] + s[left][j-1]*s[right][h] + s[left][j-1]*s[right][j-1] 1<=h<=j-2,1<=left, right <i and left + right + 1 = i
优化:满足这种条件的树的节点数一定为奇数;最大高度不会超过(N+1)/2;
#include <stdio.h> #include <string.h> int s[100][100]; int main(){ freopen("nocows.in", "r", stdin); freopen("nocows.out", "w", stdout); int N, K; scanf("%d%d", &N, &K); memset(s,0,sizeof(s));//s[i][j] i*2+1 nodes of height j s[0][1] = 1; if ((N & 1) == 0) printf("0/n"); else { N = (N-1) >> 1; for (int i = 1; i <= N; i++) { int maxh = i+1; if (K < maxh) maxh = K; for (int h = 1; h <= maxh; h++) for (int j = 0; j < i; j++) { for (int hh = 1; hh < h-1; hh++) s[i][h] = (s[i][h] + s[j][hh]*s[i-j-1][h-1] + s[i-j-1][hh]*s[j][h-1]) % 9901; s[i][h] = (s[i][h] + s[j][h-1]*s[i-j-1][h-1]) % 9901; } } printf("%d/n", s [K]); } return 0; }
题目三:Zero Sum
算法:DFS
注意:算的时候要从左向右算,从右向左算稍麻烦;
#include <stdio.h> #include <string.h> int num[10], calc[10]; int n; void dfs(int depth) { if (depth == n) { memset(num,0,sizeof(num)); int len = 0; num[0] = 1; for (int i = 1; i < n; i++) if (calc[i] == 0) num[len] = num[len]*10+(i+1); else num[++len] = (i+1); len =0; for (int i = 1; i < n; i++) if (calc[i] == 1) { num[len+1] += num[len]; len++; } else if (calc[i] == 2){ num[len+1] = num[len] - num[len+1]; len++; } if (num[len] == 0) { printf("1"); for (int i = 1; i < n; i++) { if (calc[i] == 0) printf(" "); else if (calc[i] == 1) printf("+"); else printf("-"); printf("%d", i+1); } printf("/n"); } return; } for (int i = 0; i <= 2; i++) { calc[depth] = i; dfs(depth+1); calc[depth] = 0; } } int main(){ freopen("zerosum.in", "r", stdin); freopen("zerosum.out", "w", stdout); scanf("%d", &n); memset(calc,0,sizeof(calc)); dfs(1); return 0; }
题目四:Money Systems
算法:DP 背包
小知识:INT64在DEV-C++的g++编译器中printf("%I64d",n),而在GNU中要写成printf("%lld",n)
#include <stdio.h> #include <string.h> long long s[10001]; int main(){ freopen("money.in", "r", stdin); freopen("money.out", "w", stdout); int V, N; scanf("%d%d", &V, &N); memset(s,0,sizeof(s)); s[0] = 1; int unit; for (int i = 0; i < V; i++) { scanf("%d", &unit); for (int v = unit; v <=N; v++) s[v] += s[v-unit]; } printf("%lld/n", s ); return 0; }
题目五:Controlling Company
算法:DFS/BFS
关键是要理解题目中的规则
(1)不解释(2)不解释(3)你的控制的公司称为子公司,则子公司的子公司仍然是你的公司,也受你的管辖
这道题实质是图论的题目,可以用邻接表来存贮,哪种搜索随便了。第一条规则在搜索时意味着你先把自己作为本体去拓展
#include <stdio.h> #include <string.h> const int maxn = 101, max = maxn*maxn/2; int own[maxn]; bool vis[maxn]; int first[maxn], next[max], v[max], w[max]; void dfs(int x) { if (vis[x]) return; vis[x] = true; for (int now = first[x]; now >= 0; now = next[now]) { own[v[now]] += w[now]; if (own[v[now]] > 50) dfs(v[now]); } } int main(){ freopen("concom.in", "r", stdin); freopen("concom.out", "w", stdout); int n; scanf("%d", &n); int m = 0, u; for (int i = 1; i <= maxn-1; i++) first[i] = -1; for (int i = 0; i < n; i++) { scanf("%d%d%d", &u, &v[i], &w[i]); next[i] = first[u]; first[u] = i; if (u > m) m = u; if (v[i] > m) m = v[i]; } for (int i = 1; i <= m; i++){ memset(own, 0, sizeof(own)); memset(vis, 0, sizeof(vis)); dfs(i); for (int j = 1; j <= m; j++) if (own[j] > 50 && i != j) printf("%d %d/n", i, j); } return 0; }
相关文章推荐
- USACO 2.3 Cow Pedigrees
- USACO-Section 2.3 Money Systems(DP)
- Android2.3 SDK编译出现Multiple substitutions specified in non-positional format的分析
- [USACO2.3]控制公司 Controlling Companies
- usaco 2.3 zerosum 2008.6.21
- USACO 4.4.2 Pollutant Control追查坏牛奶 题解与分析
- Android 2.3 ADB源码分析
- Android2.3 Sip简单分析
- Android2.3 Sip简单分析
- 【USACO 2.3】Money Systems(dp)
- Android2.3 SDK编译出现Multiple substitutions specified in non-positional format的分析
- USACO Training 4.2.3 Job Processing 工序安排 题解与分析
- 网规:第2章 计算机网络规划与设计-2.3网络需求分析
- USACO 2.3 Longest Prefix(乱搞)
- USACO 2.3 Money Systems(DP)
- usaco 2.3 zerosum...
- USACO 2.3 Zero Sum 题解
- usaco-2.3-zerosum-pass
- USACO2.3 五道题目
- Android2.3 SDK编译出现Multiple substitutions specified in non-positional format的分析