problem1 link

首先每$n*m$一定是一个循环,所以只需要考虑时间$[0,n*m-1]$即可。这个期间一共出现了$n$个,第i个的出现时间为$m*i$,离开的时间为$\left \lceil \frac{mi}{n} \right \rceil*n$,所有答案为:

ans=$\frac{\sum_{i=0}^{n-1}(\left \lceil \frac{mi}{n} \right \rceil*n-mi)}{n}$

=$\frac{n\sum_{i=0}^{n-1}\left \lceil \frac{mi}{n} \right \rceil-\sum_{i=0}^{n-1}mi}{n}$

=$\sum_{i=0}^{n-1}\left \lceil \frac{mi}{n} \right \rceil-\frac{(n-1)m}{2}$

设$A=\sum_{i=0}^{n-1}\left \lceil \frac{mi}{n} \right \rceil=\sum_{i=0}^{n-1}\left \lfloor \frac{mi}{n} \right \rfloor+n-X$

其中$X$是那些$mi$正好是$n$的倍数因此不需要加1的个数。

现在的问题是计算$B=\sum_{i=0}^{n-1}\left \lfloor \frac{mi}{n} \right \rfloor$

它等于$\sum_{i=0}^{n-1}\left \lfloor \frac{mi}{n} \right \rfloor=\frac{(n-1)(m-1)}{2}-\frac{gcd(n,m)-1}{2}$

这个的证明在具体数学中文版第二版第77页到第78页。

problem2 link

首先将所有的前缀编号,预处理转换表$T[id][k]$表示前缀id在输入$k$时转换到的状态,其中$k$表示数字以及星号。

然后设$f[i][id]$表示当前“fix”部分为$word$的前$i$个,且"unfix"部分的标号为id的最小操作次数。然后进行dp即可。

problem3 link

首先,在$n*m$个一个pattern中(n为高度,m为宽度),位置$(x_{1},y_{1})$到位置$(x_{2},y_{2})$的最短路径可能会经过其他重复的pattern。可以证明,如果经过该patern上面的pattern,最多只需要考虑$\left \lceil \frac{m}{2} \right \rceil^{2}$个

假设每次进入上面一个pattern是进入是第$i$列,出来时是第$j$列,$i \ne j$。那么不会出现两个pattern进入出来时的$i,j$一模一样,否则可以省略中间的一些pattern。这样考虑的话不同的$i,j$对有$\frac{m(m-1)}{2}$个,所以至多向上考虑这么多即可。

进一步考虑。将pattern的最后一行按照连续的空列分成若干组,那么很明显最多有$\left \lceil \frac{m}{2} \right \rceil$组(每隔一个空列有一个障碍格子)。跟上面同样的考虑方法,进入的组和出来的组不会有两个pattern是完全一样的,否则可以省略(因为一个组是联通的)。所以向上最多需要考虑$\left \lceil \frac{m}{2} \right \rceil^{2}$个pattern即可。

这样就可以处理出一个$m*m$的矩阵$A[i][j]$,表示从pattern的第一行的第 $i$ 列格子到达下一个pattern的第一行的第$j$列格子的最短路径。

这样的话,对于那么$r_{1},r_{2}$中间有很多pattern的情况,可以进行类似矩阵幂的优化。

code for problem1

import java.util.*;
import java.math.*;
import static java.lang.Math.*;public class Starport {public double getExpectedTime(int N, int M) {long t = (long)(N - 1) * M;long r = upper(N, M) - t / 2;if (t % 2 == 0) {return r;}return r - 0.5;}long upper(long n, long d) {if (n == 1) {return 0;}long nn = n / gcd(n, d);long p = (n - 1) / nn + 1;return lower(n, d) + n - p;}long gcd(long x, long y) {if (y == 0) {return x;}return gcd(y, x % y);}long lower(long n, long m) {return ((n - 1) * (m - 1) + gcd(n, m) - 1) / 2;}}

  

code for problem2

import java.util.*;
import java.math.*;
import static java.lang.Math.*;public class QuickT9 {static int[] D = new int[]{3, 3, 3, 3, 3, 4, 3, 4};int prefixIndex = 0;Map<String, Integer> map = new HashMap<>();    //串对应编号Map<Integer, String> mapRev = new HashMap<>(); //编号对应串Map<String, List<String>> mapForNext = new HashMap<>();  //数字串对应的串Map<String, String> mapToDigit = new HashMap<>();        //串对应的数字串List<String> allWords = new ArrayList<>();String word;int[][] g = null;int[][] f = null;public int minimumPressings(String[] t9, String word) {init(t9);this.word = word;final int n = word.length();f = new int[n + 1][prefixIndex];for (int i = 0; i <= n; ++ i) {Arrays.fill(f[i], -1);}f[0][0] = 0;for (int i = 0; i < n; ++ i) {bfs(i);}return f[n][0];}Queue<Integer> queue = new LinkedList<>();boolean[] inq = null;void bfs(int len) {if (inq == null) {inq = new boolean[prefixIndex + 1];}if (f[len][0] != -1) {queue.offer(0);}while (!queue.isEmpty()) {int st = queue.poll();inq[st] = false;for (int i = 0; i < 11; ++ i) {if (i < 9) {int nxt = g[st][i];int c = f[len][st] + 1;if (f[len][nxt] == -1 || f[len][nxt] > c) {f[len][nxt] = c;if (!inq[nxt]) {queue.offer(nxt);inq[nxt] = true;}}}else {int[] result = check(st, len, i == 10);int t = result[0];int c = result[1];if (t > 0) {if (f[len + t][0] == -1 || f[len + t][0] > f[len][st] + 1 + c) {f[len + t][0] = f[len][st] + 1 + c;}}}}}}void init(String[] all) {for (int i = 0; i < all.length; ++ i) {String[] t= all[i].split("\\W+");for (String p : t) {String x = p.trim();if (x.length() > 0) {allWords.add(x);}}}addPrefix("", "");for (int i = 0; i < allWords.size(); ++ i) {String originStr = "";String digitStr = "";String s = allWords.get(i);for (int j = 0; j < s.length(); ++ j) {digitStr += getDigit(s.charAt(j));originStr += s.charAt(j);addPrefix(originStr, digitStr);}}for (String s: mapForNext.keySet()) {Collections.sort(mapForNext.get(s));}g = new int[prefixIndex][9];for (int i = 0; i < prefixIndex; ++ i) {for (int j = 0; j < 9; ++ j) {if (j == 0) {g[i][j] = getNext(i);}else {g[i][j] = getAddDigit(i, j + 1);}}}}int[] check(int id, int preIndex, boolean isStar) {if (id == 0) {return new int[]{0,0};}String s = mapRev.get(id);String sub = word.substring(preIndex);if (isStar) {s = s.substring(0, s.length() - 1);}int comPre = 0;for (int i = 0; i < sub.length() && i < s.length(); ++ i) {if (sub.charAt(i) == s.charAt(i)) {++comPre;}else {break;}}return new int[]{comPre, s.length() - comPre};}int getNext(int id) {if (id == 0) {return 0;}String s = mapRev.get(id);String digitStr = mapToDigit.get(s);List<String> list = mapForNext.get(digitStr);int index = list.indexOf(s);String nextOriginStr = list.get((index + 1) % list.size());return map.get(nextOriginStr);}int getAddDigit(int id, int d) {String s = mapRev.get(id);String digitStr0 = mapToDigit.get(s);String digitStr1 = digitStr0 + (char)('0' + d);if (!mapForNext.containsKey(digitStr1)) {return id;}List<String> list = mapForNext.get(digitStr1);return map.get(list.get(0));}void addPrefix(String originStr, String digitStr) {if (!map.containsKey(originStr)) {map.put(originStr, prefixIndex);mapRev.put(prefixIndex, originStr);++ prefixIndex;}if (!mapForNext.containsKey(digitStr)) {mapForNext.put(digitStr, new ArrayList<>());}if (!mapForNext.get(digitStr).contains(originStr)) {mapForNext.get(digitStr).add(originStr);}mapToDigit.put(originStr, digitStr);}static char getDigit(char c) {int t = c - 'a' + 1;for (int i = 0; i < D.length; ++ i) {if (t > D[i]) {t -= D[i];}else {return (char)('2' + i);}}return 0;}
}

  

code for problem3

import java.util.*;public class InfiniteLab {final static int[] dx = {0, 0, 1, -1};final static int[] dy = {1, -1, 0, 0};final static int MAX_EXTENDED = 100;int n, m;String[] map;int[][] T;int[][][][] d;public long getDistance(String[] map, long r1, int c1, long r2, int c2) {if (r1 > r2) {return getDistance(map, r2, c2, r1, c1);}if (r1 < 0 || r1 >= map.length) {long det = r2 - r1;long b = (Math.abs(r1) / map.length + 1) * map.length;r1 = (r1 + b) % map.length;return getDistance(map, r1, c1 , r1 + det, c2);}this.map = map;n = map.length;m = map[0].length();T = new int[n][2];for (int i = 0; i < n; ++ i) {T[i][0] = T[i][1] = -1;for (int j = 0; j < m; ++ j) {if (map[i].charAt(j) == 'T') {if (T[i][0] == -1) {T[i][0] = j;}else {T[i][1] = j;}}}}d = new int[m][n][m][n + 1];cal();if (r2 <= n) {int t = d[c1][(int)r1][c2][(int)r2];if (t == Integer.MAX_VALUE) {t = -1;}return t;}long[][] a = new long[m][m];long[][] b = new long[m][m];for (int i = 0; i < m; ++ i) {for (int j = 0; j < m; ++ j) {a[i][j] = -1;if (d[i][0][j][n] != Integer.MAX_VALUE) {a[i][j] = d[i][0][j][n];}if (i == j) {b[i][j] = 0;}else {b[i][j] = -1;}}}long p = r2 / n - r1 / n - 1;while (p > 0) {if ((p & 1) == 1) {b = multipy(b, a);}a = multipy(a, a);p >>= 1;}long result = -1;for (int i = 0; i < m; ++ i) {for (int j = 0; j < m; ++ j) {if (d[c1][(int)r1][i][n] != Integer.MAX_VALUE&& b[i][j] != -1&& d[j][0][c2][(int)(r2 % n)] != Integer.MAX_VALUE) {long w = d[c1][(int)r1][i][n] + b[i][j] + d[j][0][c2][(int)(r2 % n)];if (result == -1 || result > w) {result = w;}}}}return result;}long[][] multipy(long[][] A, long[][] B) {long[][] result = new long[m][m];for (int i = 0; i < m; ++ i) {for (int j = 0; j < m; ++ j) {result[i][j] = -1;for (int k = 0; k < m; ++ k) {if (A[i][k] != -1 && B[k][j] != -1) {long t = A[i][k] + B[k][j];if (result[i][j] == -1 || result[i][j] > t) {result[i][j] = t;}}}}}return result;}int trans(int x, int y) {x %= n;if (map[x].charAt(y) == 'T') {return T[x][0] + T[x][1] - y;}return -1;}boolean empty(int x, int y) {return map[x % n].charAt(y) != '#';}void cal() {final int N = (2 * MAX_EXTENDED + 1) * n;int[][] f = new int[N][m];Queue<Integer> queue = new LinkedList<>();for (int sx = 0; sx < n; ++ sx) {for (int sy = 0; sy < m ; ++ sy) {final int startX =sx + MAX_EXTENDED * n;final int startY = sy;while (!queue.isEmpty()) {queue.poll();}for (int i = 0; i < N; ++ i) {Arrays.fill(f[i], Integer.MAX_VALUE);}f[startX][startY] = 0;queue.offer(startX * 100 + startY);while (!queue.isEmpty()) {int x = queue.peek() / 100;int y = queue.poll() % 100;int nxtCost = f[x][y] + 1;for (int i = 0; i < 4; ++ i) {int xx = x + dx[i];int yy = y + dy[i];if (xx >= 0 && xx < N && yy >= 0 && yy < m && empty(xx, yy) && f[xx][yy] > nxtCost) {f[xx][yy] = nxtCost;queue.offer(xx * 100 + yy);}}if (trans(x, y) != -1) {int y1 = trans(x, y);if (f[x][y1] > nxtCost) {f[x][y1] = nxtCost;queue.offer(x * 100 + y1);}}}for (int i = 0; i <= n; ++ i) {for (int j = 0; j < m; ++ j) {d[sy][sx][j][i] = f[i + MAX_EXTENDED * n][j];}}}}}}

  

转载于:https://www.cnblogs.com/jianglangcaijin/p/7856365.html

topcoder srm 490 div1相关推荐

  1. topcoder srm 714 div1

    problem1 link 倒着想.每次添加一个右括号再添加一个左括号,直到还原.那么每次的右括号的选择范围为当前左括号后面的右括号减去后面已经使用的右括号. problem2 link 令$h(x) ...

  2. topcoder srm 691 div1 -3

    1.给定一个$n$个顶点$n$个边的图,边是$(i,a_{i})$,顶点编号$[0,n-1]$.增加一个顶点$n$,现在选出一个顶点集$M$,对于任意的在$M$中 的顶点$x$,去掉边$(x,a_{x ...

  3. topcoder srm 706 div1

    1.给定一个迷宫,点号表示不可行,井号表示可行.现在可以改变其中的一些井号的位置.问最少改变多少个井号可以使得从左上角到右下角存在路径. 思路:设高为$n$,宽为$m$,若井号的个数$S$小于$n+m ...

  4. topcoder srm 694 div1 -3

    1.给出$n$个数字,将其分成三个非空的组,每组的权值为该组所有数字的抑或.选择一种分法使得三组的权值和最大? 思路:记录前两组的权值且三组有没有数字时第三组的值.(当前两组的值知道时第三组的权值是确 ...

  5. topcoder srm 330 div1

    problem1 link 直接模拟. import java.util.*; import java.math.*; import static java.lang.Math.*;public cl ...

  6. topcoder srm 360 div1

    problem1 link (1)$n \neq m$时,假设$n<m$,那么同一行中的$m$个数字必定都相等. (2)$n=m$时,要满足任意的$i_{1},i_{2},j_{1},j_{2} ...

  7. topcoder srm 635 div1

    problem1 link 首先枚举长度$L$.然后计算每一段长度$L$的差值最大公约数,然后差值除以最大公约数的结果可以作为当前段的关键字.然后不同段就可以比较他们的关键字,一样就是可以转化的. p ...

  8. topcoder srm 495 div1

    problem1 link 从前向后确定一下,然后再从后向前确定一下.一样的话就是可以确定的. problem2 link 首先将强连通分量缩点.理论上来说,只需要遍历所有入度为0的联通块中的一个即可 ...

  9. topcoder srm 325 div1

    problem1 link $g[i]$表示解决前$i$个的代价,那么$g[i]$是所有$g[j]+cost(j+1,i)$的最小值. import java.util.*; import java. ...

最新文章

  1. java 反编译 手游_Java反编译器(DJ Java Decompiler)
  2. 自己动手写一个服务网关
  3. [leetcode] 101. 对称二叉树
  4. jsapi支付签名_PHP实现微信支付(jsapi支付)流程步骤详解
  5. SQL查询的安全方案
  6. ES6的class方法基本用法
  7. java 验证码_如何使用Java生成随机验证码
  8. mysql 时间段在不在另外的时间段中_你知道自来水一天中哪个时间段最脏、最具毒性吗?记住这几点避开致命自来水...
  9. day33 java的多线程(5)
  10. python os.getpidos.getppid
  11. html 前端传数据流,jquery – 使用Node.js流式传输数据
  12. redis用lua实现初始值id自增
  13. 鸿蒙开发者大会邀请函,将召开史上最大规模开发者大会,华为抓紧调试“鸿蒙”系统...
  14. 将RP文件导出为HTML文件
  15. 实时时间OBS Studio插件(附下载地址与效果),实时时间插件date-and-time.lua的使用
  16. 2021-09-10 QTdesigner 介绍入门 布局
  17. 如何将ppt压缩到最小?
  18. LinuxAndroid网络前缀和子网掩码的关系
  19. android测量图片工具,ImageMeter Pro(图像测距)
  20. 基于tkinter+win32+pynput实现python的QQ微信刷屏(比某些文章稍微高级一点)

热门文章

  1. Winform中设置ZedGraph的曲线为散点图
  2. MyBatisPlus3.x代码生成器自定义模板配置
  3. MyBatisPlus条件构造器排序方法orderByDesc参数怎样构造
  4. 计算机网络总结:第一章 计算机网络和因特网
  5. 基于产生式的动物识别专家系统_钇鑫智通打造“极致流畅人脸识别闸机”
  6. 个人计算机技术分享,一个计算机类本科毕业设计分享
  7. 亿通行签约神策数据,数据赋能交通出行服务智能化创新升级
  8. 边锋游戏:用精细化运营使游戏流失率降低 26% ,只是数据驱动价值的冰山一角...
  9. Flutter React编程范式实践
  10. 【译】node js event loop part 1.1