Android应用基础学习记录
时间:2014-04-27 21:18:00
收藏:0
阅读:466
福州大学第十一届程序设计竞赛
Contest Finished!
Tag | Pro.ID | Problem Title | Ratio(AC/Submit) |
---|---|---|---|
1 | 大王叫我来巡山呐 | 80.31%(261/325) | |
2 | 防守阵地 I | 23.48%(193/822) | |
3 | shadow | 13.23%(97/733) | |
4 | 花生的序列 | 12.07%(21/174) | |
5 | 防守阵地 II | 14.98%(68/454) | |
6 | 巡了南山我巡北山 | 0.00%(0/45) | |
7 | Nostop | 20.79%(21/101) | |
8 | 卷福的难题 | 10.00%(1/10) |
本来打算当作组队赛来做的,结果队友有足球赛,还有一个有党校。。只剩下我一个人单挑了。 @.@ 还好不是很难,不然就被虐翻了。。整体来说题目比较简单,应该本来就是作为个人赛准备的。。
A题签到题
#include<algorithm> #include<iostream> #include<cstring> #include<vector> #include<cstdio> #include<cmath> #include<queue> #include<stack> #include<map> #include<set> #define LL long long #define CLR(a, b) memset(a, b, sizeof(a)) using namespace std; const int maxn = 5; const int INF = 0x3f3f3f3f; int main() { int n; while(scanf("%d", &n) != EOF) { int ans = n / 7 * 2; if(n % 7 == 6) ans ++; printf("%d\n", ans); } }
B题观察式子转移,就可以很容易发现端倪了。。
#include<algorithm> #include<iostream> #include<cstring> #include<vector> #include<cstdio> #include<cmath> #include<queue> #include<stack> #include<map> #include<set> #define LL long long #define CLR(a, b) memset(a, b, sizeof(a)) using namespace std; const int maxn = 1001000; const int INF = 0x3f3f3f3f; int a[maxn]; int main() { int n, m; while(scanf("%d%d", &n, &m) != EOF) { int ans = 0, tot = 0, sum = 0; for(int i = 1; i <= m; i ++) { scanf("%d", &a[i]); sum += a[i]; tot += i*a[i]; } ans = tot; for(int i = m + 1; i <= n; i ++) { scanf("%d", &a[i]); tot -= sum; sum -= a[i - m]; sum += a[i]; tot += a[i] * m; ans = max(ans, tot); } printf("%d\n", ans); } }C题是比较简单的树dp吧,只需要看孩子和本身有没有士兵,有的话当前点肯定会被消灭。OJ比较奇特,递归会爆栈,用vector会超时。。不幸的是两种情况我都遇到了。。
#include<algorithm> #include<iostream> #include<cstring> #include<vector> #include<cstdio> #include<cmath> #include<queue> #include<stack> #include<map> #include<set> #define LL long long #define MP make_pair #define CLR(a, b) memset(a, b, sizeof(a)) using namespace std; const int maxn = 100100; const int INF = 0x3f3f3f3f; int arm[maxn]; bool hav[maxn]; struct Edge { int u, v; }E[maxn*2]; int fir[maxn], nxt[maxn*2], tot = 0; LL d[maxn]; void AddEdge(int u, int v) { E[tot].u = u, E[tot].v = v; nxt[tot] = fir[u], fir[u] = tot ++; } LL dfs() { stack<pair<int, int> > S; CLR(d, 0); S.push(MP(1, 0)); int cnt = 0; while(!S.empty()) { int u = S.top().first, fa = S.top().second; if(fir[u] == -1) { if(hav[u]) hav[fa] = 1, d[fa] += d[u] + arm[u]; S.pop(); } else { int v = E[fir[u]].v; fir[u] = nxt[fir[u]]; if(v == fa) continue; S.push(MP(v, u)); } } return d[1]; } int main() { int n, k; while(scanf("%d%d", &n, &k) != EOF) { for(int i = 1; i <= n; i ++) { scanf("%d", &arm[i]); } CLR(hav, 0);CLR(fir, -1); tot = 0; for(int i = 0; i < k; i ++) { int u; scanf("%d", &u); hav[u] = 1; } for(int i = 1; i < n; i ++) { int u, v; scanf("%d%d", &u, &v); AddEdge(u, v); AddEdge(v, u); } printf("%lld\n", dfs()); } }D题算是一道dp吧,dp[i][j],表示到第i为为止,有j个属于第一个串,因为串的特殊性(WBWBWB),所以很容易判断当前位置的字母满足的情况。比如当前j为奇数,那么j后面肯定只能接B。。。就这样。。。
#include<algorithm> #include<iostream> #include<cstring> #include<vector> #include<cstdio> #include<cmath> #include<queue> #include<stack> #include<map> #include<set> #define LL long long #define CLR(a, b) memset(a, b, sizeof(a)) using namespace std; const int maxn = 10100; const int INF = 0x3f3f3f3f; const int MOD = 1000000007; char ch[maxn]; int dp[2][3300]; int main() { int T, n; scanf("%d", &T); while(T --) { scanf("%d%s", &n, ch); CLR(dp, 0); dp[0][0] = 1; for(int i = 0, j = 1; i < n * 2; i ++, j ++) { CLR(dp[j&1], 0); if(ch[i] == ‘B‘) { for(int k = 0; k <= n; k ++) { if(k&1) dp[j&1][k+1] = (dp[j&1][k+1] + dp[i&1][k]) % MOD; if((i-k)&1) dp[j&1][k] = (dp[j&1][k] + dp[i&1][k]) % MOD; } } else { for(int k = 0; k <= n; k ++) { if((k&1) == 0) dp[j&1][k+1] = (dp[j&1][k+1] + dp[i&1][k]) % MOD; if(((i-k)&1) == 0) dp[j&1][k] = (dp[j&1][k] + dp[i&1][k]) % MOD; } } } printf("%d\n", dp[0][n]); } }E裸线段树区间更新,区间查询,只要你不想那么多,就可以直接A掉。
#include<algorithm> #include<iostream> #include<cstring> #include<vector> #include<cstdio> #include<cmath> #include<queue> #include<stack> #include<map> #include<set> #define LL long long #define CLR(a, b) memset(a, b, sizeof(a)) #define lson l , m , rt << 1 #define rson m + 1 , r , rt << 1 | 1 using namespace std; const int maxn = 100100; const int INF = 0x3f3f3f3f; int add[maxn<<2]; int sum[maxn<<2]; void PushUp(int rt) { sum[rt] = sum[rt<<1] + sum[rt<<1|1]; } void PushDown(int rt,int m) { if (add[rt]) { add[rt<<1] += add[rt]; add[rt<<1|1] += add[rt]; sum[rt<<1] += add[rt] * (m - (m >> 1)); sum[rt<<1|1] += add[rt] * (m >> 1); add[rt] = 0; } } void build(int l,int r,int rt) { add[rt] = 0; if (l == r) { scanf("%d",&sum[rt]); return ; } int m = (l + r) >> 1; build(lson); build(rson); PushUp(rt); } void update(int L,int R,int c,int l,int r,int rt) { if (L <= l && r <= R) { add[rt] += c; sum[rt] += c * (r - l + 1); return ; } PushDown(rt , r - l + 1); int m = (l + r) >> 1; if (L <= m) update(L , R , c , lson); if (m < R) update(L , R , c , rson); PushUp(rt); } int query(int L,int R,int l,int r,int rt) { if (L <= l && r <= R) { return sum[rt]; } PushDown(rt , r - l + 1); int m = (l + r) >> 1; LL ret = 0; if (L <= m) ret += query(L , R , lson); if (m < R) ret += query(L , R , rson); return ret; } int main() { int n, m, q; while(scanf("%d%d%d", &n, &m, &q) != EOF) { build(1, n, 1); for(int i = 0; i < q; i ++) { int x; scanf("%d", &x); printf("%d\n", query(x, x + m - 1, 1, n, 1)); update(x, x + m - 1, -1, 1, n, 1); } } }
F应该是搜索吧。。。感觉无从下手,罪过。。。大致思路应该是判断是否是子串,然后在进行加字符,copy操作吧。。。我猜的。。
G题这种题第一次见到,感觉自己YY出来还是很高兴的!就是用矩阵来表示走K步之后的各个点对到达所需要的最小花费。这样的话,我们就可以用初始矩阵(表示的是1步到达的情况)不断更新,来获得走2步,走3步的到达情况。。这样的话思路就很明确了。因为题目数据比较大,我们直接用快速幂更新就可以了。(应该很容易想到这些更新是满足结合率的吧)。我还是觉得看代码清楚些。。这个OJ很个性,用lld,wa了无数次,改成cin,cout才过。。。=.=!!
#include<algorithm> #include<iostream> #include<cstring> #include<vector> #include<cstdio> #include<cmath> #include<queue> #include<stack> #include<map> #include<set> #define LL long long #define MP make_pair #define CLR(a, b) memset(a, b, sizeof(a)) using namespace std; const int maxn = 55; const LL INF = 1ll << 60; struct Matrix { LL m[maxn][maxn]; }sol, pre; int n; Matrix Add(Matrix a, Matrix b) { Matrix ret; for(int i = 1; i <= n; i ++) { for(int j = 1; j <= n; j ++) { ret.m[i][j] = INF; LL& tmp = ret.m[i][j]; for(int k = 1; k <= n; k ++) { tmp = min(tmp, a.m[i][k] + b.m[k][j]); } } } return ret; } Matrix Mul(Matrix a, int n) { Matrix ret; bool flag = false; while(n) { if(n & 1) { if(flag) ret = Add(ret, a); else ret = a; flag = true; } a = Add(a, a); n >>= 1; } return ret; } void pt(Matrix sol) { for(int i = 1; i <= n; i ++) { for(int j = 1; j <= n; j ++) printf("%lld ", sol.m[i][j]); puts(""); } } int main() { int h, k, T; scanf("%d", &T); while(T --) { scanf("%d%d%d", &n, &h, &k); for(int i = 1; i <= n; i ++) { for(int j = 1; j <= n; j ++) sol.m[i][j] = INF; } for(int i = 0; i < h; i ++) { int u, v;LL c; scanf("%d%d", &u, &v); cin >> c; sol.m[u][v] = min(sol.m[u][v], c); } sol = Mul(sol, k); if(sol.m[1][n] == INF) puts("-1"); else cout << sol.m[1][n] << endl; //printf("%lld\n", sol.m[1][n]); } }H题完全没想法,最后绝杀的那个人真厉害,ORZ~~
评论(0)