博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
2012 Multi-University #7
阅读量:5458 次
发布时间:2019-06-15

本文共 8309 字,大约阅读时间需要 27 分钟。

 

最短路+拆点 A 

题意:从1走到n,每次都是LOVE,问到n时路径是连续多个"LOVE"的最短距离.秀恩爱不想吐槽.

分析:在普通的最短路上有寻路的限制,把一个点看成4个点,表示通过某一个字符到该点的最短距离.注意自环的处理,还有距离会爆int。

#include 
const int N = 1314 + 5;const int M = 13520 + 5;const long long INF = 200000000000LL;struct Edge { int v, w, ch, nex;};Edge edge[M<<1];int head[N];int n, m, etot;void init_edge() { etot = 0; memset (head, -1, sizeof (head));}void add_edge(int u, int v, int w, char ch) { edge[etot].v = v; edge[etot].w = w; edge[etot].nex = head[u]; if (ch == 'L') { edge[etot].ch = 0; } else if (ch == 'O') { edge[etot].ch = 1; } else if (ch == 'V') { edge[etot].ch = 2; } else if (ch == 'E') { edge[etot].ch = 3; } head[u] = etot++;}struct Node { int u, id;};long long dis[N][4];int cnt[N][4];bool vis[N][4];void SPFA(int s) { for (int i=1; i<=n; ++i) { for (int j=0; j<4; ++j) { vis[i][j] = false; dis[i][j] = INF; cnt[i][j] = 0; } } dis[s][3] = 0; vis[s][3] = true; std::queue
que; que.push ((Node) {s, 3}); while (!que.empty ()) { Node now = que.front (); que.pop (); int u = now.u, id = now.id; vis[u][id] = false; for (int i=head[u]; ~i; i=edge[i].nex) { Edge &e = edge[i]; if (e.ch != (id + 1) % 4) { continue; } if (dis[e.v][e.ch] > dis[u][id] + e.w || dis[e.v][e.ch] == 0) { dis[e.v][e.ch] = dis[u][id] + e.w; cnt[e.v][e.ch] = cnt[u][id]; if (e.ch == 3) { cnt[e.v][e.ch]++; } if (!vis[e.v][e.ch]) { vis[e.v][e.ch] = true; que.push ((Node) {e.v, e.ch}); } } else if ((dis[e.v][e.ch] == dis[u][id] + e.w || dis[e.v][e.ch] == 0) && cnt[e.v][e.ch] <= cnt[u][id]) { cnt[e.v][e.ch] = cnt[u][id]; if (e.ch == 3) { cnt[e.v][e.ch]++; } if (!vis[e.v][e.ch]) { vis[e.v][e.ch] = true; que.push ((Node) {e.v, e.ch}); } } } }}int main() { int T; scanf ("%d", &T); for (int cas=1; cas<=T; ++cas) { init_edge (); scanf ("%d%d", &n, &m); char ch[2]; for (int i=0; i

 

DP+优化 C 

题意:m个时间,每个时间去取一个龙珠,代价是距离|x-ball[i].pos|,此时人移动到龙珠的位置,还有该龙珠的代价ball[i].cost,问最小代价。

分析:,另一种情况同理,先对每个时间的位置排序,求i-1时间前缀最小的转移就好了。

#include 
const int N = 50 + 5;const int M = 1000 + 5;const int INF = 0x3f3f3f3f;struct Ball { int pos, cost; bool operator < (const Ball &rhs) const { return pos < rhs.pos; }};Ball ball[N][M];int dp[N][M];int m, n, x;int main() { int T; scanf ("%d", &T); while (T--) { scanf ("%d%d%d", &m, &n, &x); for (int i=1; i<=m; ++i) { for (int j=1; j<=n; ++j) { scanf ("%d", &ball[i][j].pos); } } for (int i=1; i<=m; ++i) { for (int j=1; j<=n; ++j) { scanf ("%d", &ball[i][j].cost); } std::sort (ball[i]+1, ball[i]+1+n); } memset (dp, INF, sizeof (dp)); for (int i=1; i<=n; ++i) { dp[1][i] = abs (ball[1][i].pos - x) + ball[1][i].cost; } for (int i=2; i<=m; ++i) { int k = 1, mn = INF; for (int j=1; j<=n; ++j) { for (; k<=n && ball[i-1][k].pos <= ball[i][j].pos; ++k) { mn = std::min (mn, dp[i-1][k] - ball[i-1][k].pos); } dp[i][j] = mn + ball[i][j].pos + ball[i][j].cost; } k = n; mn = INF; for (int j=n; j>=1; --j) { for (; k>=1 && ball[i-1][k].pos > ball[i][j].pos; --k) { mn = std::min (mn, dp[i-1][k] + ball[i-1][k].pos); } dp[i][j] = std::min (dp[i][j], mn - ball[i][j].pos + ball[i][j].cost); } } int ans = INF; for (int i=1; i<=n; ++i) { ans = std::min (ans, dp[m][i]); } printf ("%d\n", ans); } return 0;}

模拟 E 

读懂题,照着模拟

#include 
int mat[4][4] = {2, 3, 1, 1, 1, 2, 3, 1, 1, 1, 2, 3, 3, 1, 1, 2};int a[4][4], tmp[4];void run() { int ans[4][4]; for (int i=0; i<4; ++i) { for (int j=0; j<4; ++j) { for (int k=0; k<4; ++k) { int t; if (mat[i][k] == 2) { t = a[k][j] << 1; if (t > 0xFF) { t ^= 0x1B; } if (t > 0xFF) { t %= (0xFF + 1); } } else if (mat[i][k] == 3) { t = a[k][j] << 1; if (t > 0xFF) { t ^= 0x1B; } t ^= a[k][j]; if (t > 0xFF) { t %= (0xFF + 1); } } else { t = a[k][j]; } tmp[k] = t; } int t = tmp[0]; for (int i=1; i<4; ++i) { t ^= tmp[i]; } ans[i][j] = t; } } for (int i=0; i<4; ++i) { for (int j=0; j<3; ++j) { printf ("%02X ", ans[i][j]); } printf ("%02X\n", ans[i][3]); }}int main() { int T; scanf ("%d", &T); while (T--) { for (int i=0; i<4; ++i) { for (int j=0; j<4; ++j) { scanf ("%X", &a[i][j]); } } run (); if (T) { puts (""); } } return 0;}

数学+快速幂 F 

题意:一个n*n的图填充颜色使得图如何反转或旋转都不会变化。

分析:考虑到是中心对称的,只要考虑1/8的图(三角形)就行了,假设总和x个。填充过的颜色的位置转移到1/8的图中(假设y个),其他的地方能涂k种颜色,答案是k^(x-y)。

#include 
const int MOD = 100000007;int pow_mod(int x, int n) { int ret = 1; while (n) { if (n & 1) { ret = (long long) ret * x % MOD; } x = (long long) x * x % MOD; n >>= 1; } return ret;}const int N = 10005;bool vis[N/2][N/2];int n, m, k;int main() { while (scanf ("%d%d%d", &n, &m, &k) == 3) { memset (vis, false, sizeof (vis)); int mid = n / 2; if (n & 1) { mid++; } for (int i=0; i
mid) { x = n + 1 - x; } if (y > mid) { y = n + 1 - y; } if (x < y) { std::swap (x, y); } vis[x][y] = true; } int c = 0; for (int i=1; i<=mid; ++i) { for (int j=1; j<=i; ++j) { if (!vis[i][j]) { c++; } } } printf ("%d\n", pow_mod (k, c)); } return 0;}

DFS序+线段树 G 

题意:给了n个人的上下级关系,每个人有能力和忠诚度,问如果上级被炒了,下属里能力比他强,忠诚度最高的是谁。

分析:其实就是给了一棵树,DFS序转换为线性序列,每一个上级管辖一段区间,按照能力从大到小排序,每次插入能力比上级强的,相同的也同时插入,询问忠诚度最高的对应人的id即是答案。

#include 
const int N = 5e4 + 5;struct Person { int sup, loy, ab, id; bool operator < (const Person &rhs) const { return ab > rhs.ab; }}p[N];int n, m;int left[N], right[N];std::map
ID;std::vector
edge[N];int tot;#define lson l, mid, o << 1#define rson mid + 1, r, o << 1 | 1int mx[(N<<1)<<2];void push_up(int o) { mx[o] = std::max (mx[o<<1], mx[o<<1|1]);}void updata(int p, int v, int l, int r, int o) { if (l == r) { mx[o] = v; return ; } int mid = l + r >> 1; if (p <= mid) { updata (p, v, lson); } else { updata (p, v, rson); } push_up (o);}int query(int ql, int qr, int l, int r, int o) { if (ql <= l && r <= qr) { return mx[o]; } int mid = l + r >> 1, ret = -1; if (ql <= mid) { ret = std::max (ret, query (ql, qr, lson)); } if (qr > mid) { ret = std::max (ret, query (ql, qr, rson)); } return ret;}void DFS(int u) { left[u] = tot++; for (auto v: edge[u]) { DFS (v); } right[u] = tot;}int ans[N];void solve() { tot = 1; DFS (0); //build (1, tot-1, 1); memset (mx, -1, sizeof (mx)); std::sort (p+1, p+n); ans[0] = -1; for (int j, i=1; i

 

转载于:https://www.cnblogs.com/Running-Time/p/5509539.html

你可能感兴趣的文章
打开eclipse出现JVM terminated.Exit Code=-1错误的解决办法
查看>>
SSH连接时出现Host key verification failed的原因及解决方法【转载】
查看>>
2017.6.7
查看>>
7. 炒股怎么看盘
查看>>
【采集层】Kafka 与 Flume 如何选择(转)
查看>>
【BZOJ1803】Spoj1487 Query on a tree III 主席树+DFS序
查看>>
jQuery 遍历 - map() 方法
查看>>
jQuery事件绑定、解绑、命名空间
查看>>
C#类,对象,构造方法
查看>>
学习笔记: AOP面向切面编程和C#多种实现
查看>>
学习笔记: 特性Attribute详解,应用封装
查看>>
java的垃圾回收方法finalize()
查看>>
Android NDK构建资料
查看>>
Linux搭建Scrapy爬虫集成开发环境
查看>>
LeetCode(21)题解:Merge Two Sorted Lists
查看>>
Ubuntu 16.04 samba 配置
查看>>
Python——文件操作
查看>>
OPENCV学习笔记2-3_图像遍历(迭代器)
查看>>
DEM转换为Features
查看>>
会计简要学习
查看>>