题目链接:点击...
对于这道题的解题思路,我只能说很吊,无结构无算法才是最高境界吧!!!!
但是对于这道题的评判系统,我只能说卧槽了!!!! java评测有误!!!!
还有就是题目表述有问题!!! 请看:现已知共有M个士兵,编号为0~M!!
说了有M,编号的个数确实(M+1)个!!!!
5 3 2 1 3 2 2 4 1 5 5 10//但是看这组测试数据,编号确实从1到M,但是呢!!!!测试数据里竟然有编号为0的!!!
真实醉了,醉睡过去了!!!
但是呢,吐槽归吐槽,这道题的解法还是相当新颖的,美,真的很美!!!
题目大意:编号为1-M的士兵,都是连续杀敌的,杀敌之后每个人都增加一定的军工,然后询问从start到end的士兵的军工和。
思路:第一开始,我还以为是树状数组,插线问线,但是又想了想,数组数组是对于动态插入,查询效率比较高,而这道题是静态的,
就是都插入了,再查询!!! 那树状数组就不一定是最优了!!!
上码,码上解释!!!
import java.io.BufferedInputStream; import java.io.IOException; import java.io.InputStream; public class Main { public static void main(String[] args) throws IOException { InputStream mis = new MyInputStream(); int[] arr = new int[1000005]; int n, inputN, queryN, start, end, add; n = mis.read(); inputN = mis.read(); queryN = mis.read(); while (inputN-- > 0) { start = mis.read(); end = mis.read(); add = mis.read(); ///
//这两句是绝了!!! 我们输入的是从start到end,每个士兵都增加军工add,
//但是这里只对arr[start]和arr[end+1]做处理,因为后面要通过一个for循环,把前面一项
//加到当前一项,在start-end之间的都会加上add,在end之后加上add,又减去add!!!
//真不知道这种解法是谁想出来的!!!!!! arr[start] += add; arr[end + 1] -= add;
/// }
//一个for循环,把arr[i]变成第i士兵的军工
for (int i = 1; i <= n; i++) { arr[i] += arr[i - 1]; }
//这个for循环,把arr[i]变成第一个到第i个士兵军工的总和!!!
for (int i = 1; i <= n; i++) { arr[i] = (arr[i] + arr[i - 1]) % 10003; } while (queryN-- > 0) { start = mis.read(); end = mis.read(); if (start == 0) { start = 1; }
<span style="white-space:pre"> </span>//这里,有可能不确定start跟end的大小关系!!! System.out.println((arr[end] - arr[start - 1] + 10003) % 10003); } mis.close(); mis = null; } } class MyInputStream extends InputStream {//改写输入流,提高速度 private BufferedInputStream bis = new BufferedInputStream(System.in); public int read() throws IOException { int i, x = 0; while ((i = bis.read()) < '0' || i > '9') ;//找到第一个数符 while (i >= '0' && i <= '9') {//如果遇到非数符就退出 x = x * 10 + i - '0'; i = bis.read(); } return x; } }
这个代码在nyoj上过不了!!!!!它的评测系统有错误!!!!坑爹!!!