2017 Wuhan University Programming Contest (Online Round)(补题补题)

来源:互联网 发布:广场舞扰民知乎 编辑:程序博客网 时间:2024/05/22 05:15

A

设S是两地的总距离, x是从west方向过来的车的速度, y是east方向过来的车的速度,根据题意有

S = 60 / y (x + y)

2S = (S - 90 + 60) / y (x + y)

比一下就出来了


B

这题挺有意思的、

题意:就说一颗n个节点,n-1条边,有m种颜色,然后给出每一个节点能涂上的颜色,现在要求相邻的两个节点之间颜色不能相同,问一共有多少种涂色方案

思路:dp1[i][j] 代表以点i为节点的子树在节点i涂上颜色j时候的总方案数,dp2[i]代表以节点i为子树的方案数

#include <cstdio>#include <cmath>#include <cstring>#include <cctype>#include <sstream>#include <iostream>#include <algorithm>#include <vector>#include <queue>#include <string>#include <stack>#include <map>#include <set>#include <utility>using namespace std;#define LL long long#define pb push_back#define mk make_pair#define pill pair<int, int>#define mst(Arr, x)memset(Arr, x, sizeof(Arr))#define REP(i, x, n)for(int i = x; i < n; ++i)const int qq = 1e4 + 10;const int MOD = 1e7 + 9;vector<int> G[qq];LL dp1[qq][23], dp2[qq];int color[qq][23];int n, m;void Init(){REP(i, 0, n + 1){G[i].clear();}mst(dp2, 0);}void Dfs(int u, int fa){for(int i = 1; i <= m; ++i)dp1[u][i] = color[u][i];for(int v : G[u]){if(v == fa)continue;Dfs(v, u);for(int i = 1; i <= m; ++i){dp1[u][i] *= (dp2[v] - dp1[v][i] + MOD) % MOD;dp1[u][i] %= MOD;}}for(int i = 1; i <= m; ++i)dp2[u] += dp1[u][i];dp2[u] %= MOD;}int main(){while(scanf("%d%d", &n, &m) != EOF){Init();REP(i, 1, n){int a, b;scanf("%d%d", &a, &b);G[a].pb(b), G[b].pb(a);}REP(i, 0, n)REP(j, 0, m){scanf("%d", &color[i + 1][j + 1]);}Dfs(1, -1);printf("%lld\n", dp2[1]);}return 0;}


C

题意:你可以删除一些数,要求剩下组成的数可以被6整除,并且不含前导零,问最多可以剩下多少位数

思路:dp[i][j]代表前i位在余数为j的时候的最大位数,注意0存在的情况

#include <cstdio>#include <cmath>#include <cstring>#include <cctype>#include <sstream>#include <iostream>#include <algorithm>#include <vector>#include <queue>#include <string>#include <stack>#include <map>#include <set>#include <utility>using namespace std;#define LL long long#define pb push_back#define mk make_pair#define pill pair<int, int>#define mst(Arr, x)memset(Arr, x, sizeof(Arr))#define REP(i, x, n)for(int i = x; i < n; ++i)const int qq = 1e5 + 10;const int INF = 1e9 + 10;char st[qq];int dp[qq][7];int main(){while(scanf("%s", st + 1) != EOF){int n = strlen(st + 1);for(int i = 0; i <= n; ++i)for(int j = 0; j < 6; ++j)dp[i][j] = -INF;int ans = -INF;for(int i = 1; i <= n; ++i)if(st[i] == '0')ans = 1;for(int i = 1; i <= n; ++i){int t = st[i] - '0';if(t != 0)dp[i][t % 6] = 1;for(int j = 0; j < 6; ++j)dp[i][j] = max(dp[i][j], dp[i - 1][j]);for(int j = 0; j < 6; ++j)dp[i][(j * 10 + t) % 6] = max(dp[i][(j * 10 + t) % 6], dp[i - 1][j] + 1);ans = max(ans, dp[i][0]);}if(ans > 0)printf("%d\n", ans);elseprintf("-1s\n");}return 0;}


E

矩阵快速幂的裸题

 令C=A*A,那么C(i,j)=ΣA(i,k)*A(k,j),实际上就等于从点i到点j恰好经过2条边的路径数(枚举k为中转点)。

只是这里是在k步内达到就可以了,也就是你到达n点后就可以了,但是快速幂还要继续下去,所以mar[n][n] = 1

#include <cstdio>#include <cmath>#include <cstring>#include <cctype>#include <sstream>#include <iostream>#include <algorithm>#include <vector>#include <queue>#include <string>#include <stack>#include <map>#include <set>#include <utility>using namespace std;#define LL long long#define pb push_back#define mk make_pair#define pill pair<int, int>#define mst(Arr, x)memset(Arr, x, sizeof(Arr))#define REP(i, x, n)for(int i = x; i <= n; ++i)const int qq = 105;const int MOD = 1e9 + 7;int n, m, p;struct Rec{LL mar[qq][qq];Rec(){mst(mar, 0);}Rec operator * (const Rec &a)const{Rec tmp;REP(i, 1, n)REP(j, 1, n){tmp.mar[i][j] = 0;REP(k, 1, n){tmp.mar[i][j] = (tmp.mar[i][j] + mar[i][k] * a.mar[k][j] + MOD) % MOD;tmp.mar[i][j] = (tmp.mar[i][j] + MOD) % MOD;}}return tmp;}}ans;Rec Quick(){Rec tmp;for(int i = 1; i <= n; ++i)        tmp.mar[i][i] = 1;while(p){if(p & 1)tmp = tmp * ans;p >>= 1;ans = ans * ans;}return tmp;}int main(){scanf("%d%d", &n, &m);REP(i, 1, m){int a, b;scanf("%d%d", &a, &b);if(a != n)ans.mar[a][b] = 1; if(b != n)ans.mar[b][a] = 1;}ans.mar[n][n] = 1;scanf("%d", &p);Rec t;t = Quick();printf("%lld\n", (t.mar[1][n] + MOD) % MOD);return 0;}



G

这题就是个求逆序数。

#include <cstdio>#include <cmath>#include <cstring>#include <cctype>#include <sstream>#include <iostream>#include <algorithm>#include <vector>#include <queue>#include <string>#include <stack>#include <map>#include <set>#include <utility>using namespace std;#define LL long long#define pb push_back#define mk make_pair#define pill pair<int, int>#define mst(Arr, x)memset(Arr, x, sizeof(Arr))#define REP(i, x, n)for(int i = x; i < n; ++i)const int qq = 1e6 + 10;int sum[qq], num[qq];int n;int lowbit(int x){return x&(-x);}int GetSum(int x){int ans = 0;while(x > 0){ans += sum[x];x -= lowbit(x);}return ans;}void UpDate(int x){while(x <= qq){sum[x] += 1;x += lowbit(x);}}int main(){while(scanf("%d", &n) != EOF){mst(sum, 0);REP(i, 0, n){scanf("%d", num + i);}LL ans = 0;for(int i = n - 1; i >= 0; --i){ans += GetSum(num[i] - 1);UpDate(num[i]);}printf("%lld\n", ans);}return 0;}




0 0
原创粉丝点击