1001 A+B Format
用时6分钟
先计算a+b,再转换成字符串,再转换成字符数组,从后往前扫一遍,每3位加一个逗号,最开始的负号(如果有的话)要特判出来
import java.io.BufferedInputStream; import java.util.Scanner; public class PAT1001 { public static void main(String[] args) { Scanner scanner = new Scanner(new BufferedInputStream(System.in)); int a, b; a = scanner.nextInt(); b = scanner.nextInt(); int c = a + b; String s = String.valueOf(c); char[] array = s.toCharArray(); int count = 0; String result = ""; for(int i = array.length - 1; i >= 0; i--) { if(array[i] == '-') { result = "-" + result; continue; } if(count == 3) { result = "," + result; count = 0; } result = array[i] + result; count++; } System.out.println(result); } }
1002 A+B for Polynomials
用时26分钟
这题我真的是WA出花了。。。。。。
整体思路是用木桶,需要注意的点一共有以下几个:
①由于数据类型是double,所以在检查木桶中数值是否不为0的时候不能直接和0比较,要和1e-8或者0.1进行比较
②在比较的时候要取绝对值,不能直接比较
③如果整个多项式的和是0,要注意不能输出“0 ”,必须输出"0"(真要命
④每一行的最后一项后面不能跟空格,所以需要用计数器进行特判
#include <iostream> #include <cstdio> #include <algorithm> double barrel[1005]; using namespace std; double abs(double a) { return a > 0? a : -a; } int main() { int k; for(int tt = 0; tt < 2; tt++) { cin >> k; for(int i = 0 ; i < k; i++) { int b; scanf("%d", &b); double t; scanf("%lf", &t); barrel[b] += t; } } int cnt = 0; for(int i = 1004; i >= 0; i--) { if(abs(barrel[i]) >= 0.1) { cnt++; } } printf("%d", cnt); if(cnt != 0) putchar(' '); else return 0; int cc = 0; for(int i = 1004; i >= 0; i--) { if(abs(barrel[i]) >= 0.1) { cc++; if(cc != cnt) printf("%d %.1lf ", i, barrel[i]); else printf("%d %.1lf ", i, barrel[i]); } } return 0; }
1003 Emergency
用时41分钟
这题是朴素的dijkstra(O(N²)复杂度即可过)(不过需要记录路径数),注意inf一定要开的够大/在比较时对inf进行特判,否则会WA(边权超过了你设定的inf,会在松弛时把inf松弛进去)
#include <iostream> #include <cstdio> #include <algorithm> #include <vector> using namespace std; #define inf 100000000 #define N 600 int n,m; int dis[N]; int rescue[N]; int graph[N][N]; //邻接矩阵 int pathCount[N]; int maxRescue[N]; int done[N]; void dijkstra(int s) { //朴素dijkstra for(int i = 0; i < N; i++) dis[i] = inf; dis[s] = 0; maxRescue[s] = rescue[s]; pathCount[s] = 1; for(int j = 0; j < n; j++) { //共计进行n次 //找最小值 int minPos = -1; int minValue = inf; for(int i = 0;i < n; i++) { if(!done[i] && dis[i] < minValue) { minPos = i; minValue = dis[i]; } } //cout << "minpos=" << minPos << endl; done[minPos] = 1; //更新 for(int i = 0; i < n; i++) { if(!done[i] && graph[minPos][i] != inf && dis[i] >= minValue + graph[minPos][i]) { dis[i] = minValue + graph[minPos][i]; pathCount[i] += pathCount[minPos]; //记录路径数 maxRescue[i] = max(maxRescue[i], rescue[i] + maxRescue[minPos]); //记录最大rescue值 } } } } int main() { int s, t; cin >> n >> m >> s >> t; for(int i = 0; i < n; i++) scanf("%d", &rescue[i]); int u,v, w; for(int i = 0; i < N ; i++) for(int j = 0;j < N; j++) graph[i][j] = (i==j)? 0 : inf; for(int i = 0; i < m; i++) { scanf("%d%d%d", &u, &v, &w); if(graph[u][v] > w) { graph[u][v] = graph[v][u] = w; } } dijkstra(s); printf("%d %d ", pathCount[t], maxRescue[t]); return 0; }
1004 Counting Leaves
用时22分钟
难得的一次AC(笑哭)
题意是问一棵树的每一层上有多少个叶子结点,这里涉及到按层遍历,所以整体思路是一个bfs,传统的bfs是用一个单向队列q,但是我们需要知道某一层到哪里结束,这里我使用了另外一个队列qq,来记录每一层的最后一个结点(其实在bfs下,qq队列里最多就只有两个元素,用变量记录就行)。为了方便地获取这一层的节点的最后一个孩子(这一层的节点的最后一个孩子不一定是这一层最后一个节点的孩子,最后一个节点可能没有孩子),我将q从单向队列换成了双向队列,这样我只需要拿最后一个进队的出来,就直接取到这一层的节点的最后一个孩子了。
#include <iostream> #include <queue> #include <list> #include <vector> #include <cstdio> #include <algorithm> using namespace std; int n, m; vector<int> graph[105]; bool vis[105]; //记录这个节点是否是一个叶子结点 int main() { for(int i = 0; i < 105; i++) vis[i] = false; cin >> n >> m; for(int i = 0; i <m; i++) { int u; cin >> u; int k; cin >> k; if(k != 0) vis[u] = true; for(int j = 0; j < k; j++) { int v; cin >> v; graph[u].push_back(v); } } list<int > q; vector<int> vvv; //用来存放结果 queue<int> qq; //用来存放这一层到哪个结点 q.push_back(1); qq.push(1); int cnt = 0; while(!q.empty()) { //bfs int u = q.front(); q.pop_front(); if(!vis[u]) { //这是一个叶子结点,叶子计数器+1 cnt++; } else { //这不是一个叶子结点,开始遍历他的所有边 for(int i = 0; i < graph[u].size(); i++) { //这里是树,所以直接入队就行,不用判是否已经在队列中了,它一定不在队列中 q.push_back(graph[u][i]); } } if(u == qq.front()) { //这一层的遍历结束了 vvv.push_back(cnt); cnt = 0; qq.pop(); qq.push(q.back()); //最后入队的这个元素就是下一层的结束 } } for(int i = 0; i < vvv.size() - 1; i++){ printf("%d ", vvv[i]); } printf("%d ", vvv[vvv.size()-1]); return 0; }