【九度】2014年王道论坛计算机考研机试全真模拟考试解题报告
来源:互联网 发布:薄层层析硅胶板 淘宝 编辑:程序博客网 时间:2024/05/17 22:49
时间限制:1 秒内存限制:128 兆特殊判题:否提交:764解决:321
题目描述:
如图,给定任意时刻,求时针和分针的夹角(劣弧所对应的角)。
输入:
输入包含多组测试数据,每组测试数据由一个按hh:mm表示的时刻组成。
输出:
对于每组测试数据,输出一个浮点数,代表时针和分针的夹角(劣弧对应的角),用角度表示,结果保留两位小数。
样例输入:
03:00
14:45
样例输出:
90.00
172.50
来源:
2014年王道论坛计算机考研机试全真模拟考试
简单题,分别模拟时针和0点之间的度数,分针和0点之间的度数。
其中时针和0之间的度数,由两部分组成。1)、当前整点当前时间点(double)hour/12*360,当然记得转double,超过12点记得转换hour -= 12。2)、分钟数占一个小时百分比。每个小时间隔是360/12 = 30度,(double)minute/60*30。
分针和0之间的度数,(double)minute / 60 * 360;
二者大减小,或者求绝对值abs,如果大于180度,记得转换。
Java AC
import java.util.Scanner;import java.util.regex.Pattern; public class Main { /* * 2014年3月16日21:18:33 */ public static void main(String[] args) throws Exception{ Scanner scanner = new Scanner(System.in); while (scanner.hasNext()) { String time = scanner.next(); String timeMsg[] = time.split(Pattern.quote(":")); int hour = Integer.parseInt(timeMsg[0]); int minute = Integer.parseInt(timeMsg[1]); if(hour > 12){ hour -= 12; } double degree1 = (double)hour / 12 * 360 + (double)minute / 60 * 30; double degree2 = (double)minute / 60 * 360; double max = Math.max(degree1, degree2); double min = Math.min(degree1, degree2); double result = max - min; if(result > 180){ result = 360 - result; } System.out.printf("%.2f\n",result); } }} /************************************************************** Problem: 1553 User: wzqwsrf Language: Java Result: Accepted Time:450 ms Memory:15852 kb****************************************************************/2、题目1554:区间问题
时间限制:1 秒内存限制:128 兆特殊判题:否提交:921解决:68
题目描述:
给定一个数组,判断数组内是否存在一个连续区间,使其和恰好等于给定整数k。
输入:
输入包含多组测试用例,每组测试用例由一个整数n(1<=n<=10000)开头,代表数组的大小。
接下去一行为n个整数,描述这个数组,整数绝对值不大于100。
最后一行为一个整数k(大小在int范围内)。
输出:
对于每组测试用例,若存在这个连续区间,输出其开始和结束的位置,s,e(s <= e)。
若存在多个符合条件的输出,则输出s较小的那个,若仍然存在多个,输出e较小的那个。
若不存在,直接输出"No"。
样例输入:
5
-1 2 3 -4 9
5
3
-1 2 -3
7
2
-1 1
0
样例输出:
2 3
No
1 2
来源:
2014年王道论坛计算机考研机试全真模拟考试
解题思路:
暂时给出这两种思路吧,一个时间复杂度不是很好。一个很耗空间。如果以后有好的思路,会继续优化。
1、暴力搜索,O(N*N),肯定会超时。但是对暴力搜索稍微优化,判断如果k比连续子数组和的最大值还大,比最小值还小,那么肯定无解了,直接输出No。否则在暴力搜索,最长时间O(N*N),C++过了。
2、稍微有点动态规划的思想,求出sumArr。这样一转换,就是在一个数组中,求解之差为k的两数是否存在,如果存在,输出index。
1、C++ AC
#include <stdio.h>const int maxn = 10002;int array[maxn]; int main(){ int n, k, i, j; while(scanf("%d",&n) != EOF){ int max = -100; int min = 100; int tempMax = 0; int tempMin = 0; for(i = 0; i < n; i++){ scanf("%d", &array[i]); if(tempMax < 0){ tempMax = array[i]; }else{ tempMax += array[i]; } max = max > tempMax ? max : tempMax; if(tempMin > 0){ tempMin = array[i]; }else{ tempMin += array[i]; } min = min < tempMin ? min : tempMin; } scanf("%d",&k); if(k < min || k > max){ printf("No\n"); continue; } bool flag = false; for(i = 0; i < n; i++){ int tempSum = 0; for(j = i; j < n; j++){ tempSum += array[j]; if(tempSum == k){ flag = true; printf("%d ",(i+1)); printf("%d\n",(j+1)); break; } } if(flag){ break; } } if(!flag){ printf("No\n"); } } return 0;}/************************************************************** Problem: 1554 User: wzqwsrf Language: C++ Result: Accepted Time:990 ms Memory:1060 kb****************************************************************/2、Java AC
import java.io.BufferedReader;import java.io.InputStreamReader;import java.io.StreamTokenizer;import java.util.ArrayList;import java.util.Collections;import java.util.HashMap;import java.util.List;import java.util.Map; public class Main { /* * 1554 */ public static void main(String[] args) throws Exception { StreamTokenizer st = new StreamTokenizer(new BufferedReader( new InputStreamReader(System.in))); while (st.nextToken() != StreamTokenizer.TT_EOF) { int n = (int) st.nval; int array[] = new int[n+1]; int sumArr[] = new int[n+1]; Map<Integer, Integer> sumMap = new HashMap<Integer, Integer>(); for(int i = 1; i <= n; i++){ st.nextToken(); array[i] = (int)st.nval; sumArr[i] = sumArr[i-1] + array[i]; if (!sumMap.containsKey(sumArr[i])) { sumMap.put(sumArr[i], i); } } st.nextToken(); int k = (int) st.nval; boolean flag = false; List<Node> nodeList = new ArrayList<Node>(); int start = 0; int end = 0; for (int i = n; i > 0; i--) { if (sumArr[i] == k) { flag = true; start = 1; end = i; Node node = new Node(start, end); nodeList.add(node); continue; } if (i == 1 && sumArr[i] != k) { continue; } int tempNum = sumArr[i] - k; if (sumMap.containsKey(tempNum)) { int tempStart = sumMap.get(tempNum)+1; if (tempStart > i) { continue; } flag = true; start = sumMap.get(tempNum)+1; end = i; Node node = new Node(start, end); nodeList.add(node); } } if(!flag){ System.out.println("No"); continue; } Collections.sort(nodeList); Node node = nodeList.get(0); System.out.println(node.start + " " + node.end); } } private static class Node implements Comparable<Node>{ int start ; int end; public Node(int start, int end) { super(); this.start = start; this.end = end; } public int compareTo(Node o) { if (this.start == o.start) { return this.end - o.end; }else { return this.start - o.start; } } }} /************************************************************** Problem: 1554 User: wangzhenqing Language: Java Result: Accepted Time:2810 ms Memory:132680 kb****************************************************************/
3、题目1555:重复子串
时间限制:3 秒内存限制:256 兆特殊判题:否提交:396解决:41
题目描述:
给定一个由小写字母组成的字符串,求它的所有连续子串中,出现过至少两次,且至少有一对出现的重复子串是不重合的连续子串个数。
如给定字符串aaaa,aa和a,符合条件,aaa不符合条件(出现重合),故答案为2。
输入:
输入包含多组测试用例,每组测试用例包含一个字符串,由小写字母组成,其长度不大于1000。
输出:
对于每组测试数据,输出一个整数,代表符合条件的子串个数。
样例输入:
aaaa
aaa
样例输出:
2
1
来源:
2014年王道论坛计算机考研机试全真模拟考试
其实我很久都看懂题目是什么意思。
好嘛,有点晦涩难懂。
题目的意思应该是求解,字符串s的子串。但是这个子串是有要求的。
1、这个子串出现过至少两次。
2、子串合并起来应该是s本身或者是s的子串。
举例来说,aaaa,子串为aaa,aa和a,其中aaa也出现了2次,就是0到3位置以及2到4位置,但是aaa重合才能够成s,所以aaa不是。
再比如abab,子串有a,b,ab以及aba和bab。a,b和ab都出现了2次,并且互相不重合。
基本思路,声明一个set,用来存放满足条件的子串。
双重循环,时间复杂度是O(N*N),其实不到n,最多也就n/2*n。
针对每个从i处开始长度为j的子串,有以下操作:
1)、如果这个子串已经在set中存在了,就没必要在判断了,直接continue。
2)、判断在剩余的字符串中是否存在。这里对Java来说,可以采用indexOf方法判断一个字符串是不是另一个字符串的子串。
如果存在,那么set中add就可以了。
如果不存在,这里注意剪枝。因为从i开始长度为j的字符串在余下的字符串中已经不存在了,所以长度即使再增加,也不会存在了,直接break就退出当前循环了。
最后set的长度就是满足条件的子串的个数。
C++太渣了,不太会处理字符串,先给出Java吧。
Java AC
import java.io.BufferedReader;import java.io.InputStreamReader;import java.io.StreamTokenizer;import java.util.HashSet;import java.util.Set; public class Main { /* * 1555 2014年3月19日22:07:16 */ public static void main(String[] args) throws Exception { StreamTokenizer st = new StreamTokenizer(new BufferedReader( new InputStreamReader(System.in))); while (st.nextToken() != StreamTokenizer.TT_EOF) { Set<String> set = new HashSet<String>(); String input = st.sval; int len = input.length(); for (int i = 0; i < len; i++) { int j = 1; while (j * 2 + i <= len) { String before = input.substring(i, i + j); if (set.contains(before)) { j++; continue; } String next = input.substring(i + j); if (next.indexOf(before) != -1) { set.add(before); j++; }else{ break; } } } System.out.println(set.size()); } }} /************************************************************** Problem: 1555 User: wzqwsrf Language: Java Result: Accepted Time:970 ms Memory:25924 kb****************************************************************/
4、题目1556:机场管制
时间限制:1 秒内存限制:128 兆特殊判题:否提交:66解决:11
题目描述:
已知飞机降落由二个阶段组成:
1:接受进近管制。
2:降落
现给定一天中飞机进入进近管制区准备降落的情况,根据规则输出对飞机的管制命令。
规则如下:
A.飞机信息由二部分组成:1.航班号(由不多于10个字符的字符串组成)。2.优先级(分为A,B,C三等)。
B.当跑道空闲时,已经进入进近管制区的飞机可以降落,其中优先级为A的飞机优先降落,B次之,C再次.相同优先级的飞机,先进入管制区的优先降落.
C.有三条跑道(1,2,3)可以使用,当对某飞机发出可以在某条跑道降落的命令后,二十分钟内该跑道将不被使用。即,若在9:31分对某飞机发出可在该跑道降落的命令后,至少在9:51分才能重新命令其它飞机在该跑道降落。
D.为防止低优先级的飞机在空中等待的时间过长,规定每过二十分钟,将B优先级中进入管制区时间最早的飞机提升到A,同时将C优先级中进入管制区时间最早的飞机提升到B,若没有则不提升。同时设定其进入进近管制区的时间为当前时间。一天中第一次提升时间为00:20,第二次为00:40,依此类推。
E.当跑道空闲时,优先使用1号跑道,2号跑道次之,3号跑道再次。
注意:
1.当飞机的优先级被提升到k,而重新设定其到达时间时,恰好有一架优先级为k的飞机到达,则优先级被提升的飞机的到达时间被视为早于该刚到达的飞机(数值上仍保持一致).
2.在每一分钟其逻辑顺序如下,若有飞机可以降落,使其降落。若有飞机需要被提升优先级,则提升优先级。最后处理刚进入管制区的飞机。命令的输出也按照该逻辑。
3.处理的最低时间间隔为分钟。
4.同时的降落按照跑道1、2、3的顺序输出命令。同时的升级先输出B升级A,再输出C升级B。
输入:
输入包含多组测试数据,每组测试数据由一个整数n(1<= n <= 200)开头,表示总计的航班数。
接下去n行,每行表示一个航班,格式为
hh:mm name level
表示优先级为level的航班name,在时间hh:mm进入管制区。name保证不会重复。
飞机按照时间递增的顺序给出,不存在两架飞机同时到达的情况。可能的时间区间为00:00到23:39,这里不考虑跨00:00飞机。
输出:
对于不同的情况,输出如下命令
当飞机name进入管制区时输出:
hello name.@hh:mm
当飞机name允许在k号跑道降落时输出
name,landing on runway k.@hh:mm
当飞机name的优先级从k提升到j时,输出
name,level up from k to j.@hh:mm
其中hh:mm为发出该条命令的时间
样例输入:
10
10:00 AC100 C
10:01 AC765 C
10:02 AC777 C
10:03 AC009 C
10:04 AC101 C
10:05 AC327 B
10:06 AC328 A
10:07 AC001 B
10:08 AC002 B
10:09 AC003 B
样例输出:
hello AC100.@10:00
AC100,landing on runway 1.@10:01
hello AC765.@10:01
AC765,landing on runway 2.@10:02
hello AC777.@10:02
AC777,landing on runway 3.@10:03
hello AC009.@10:03
hello AC101.@10:04
hello AC327.@10:05
hello AC328.@10:06
hello AC001.@10:07
hello AC002.@10:08
hello AC003.@10:09
AC327,level up from B to A.@10:20
AC009,level up from C to B.@10:20
AC328,landing on runway 1.@10:21
AC327,landing on runway 2.@10:22
AC001,landing on runway 3.@10:23
AC002,level up from B to A.@10:40
AC101,level up from C to B.@10:40
AC002,landing on runway 1.@10:41
AC003,landing on runway 2.@10:42
AC009,landing on runway 3.@10:43
AC101,level up from B to A.@11:00
AC101,landing on runway 1.@11:01
来源:
2014年王道论坛计算机考研机试全真模拟考试
这个应该是典型的模拟题,瞬间联想到题目1540:麦霸(解题思路可以参考Jobdu 题目1540:麦霸),但是好像想错方向了。
麦霸这个题可以根据当前时间进行判断是否要做操作(这个题也可以将list改为队列)。本题循环的应该是当前时间,参考了别人写的代码。
基本思路应该是:
1、有三个队列,存的是三个级别的进入管制区的飞机。
2、有三个时间,存的是当前跑道释放的时间。
3、每个时间点,需要做三件事。
1)、判断当前管制区是否有飞机,跑道是否有空余。如果二者条件都符合,将当前队列中的第一架飞机落地。
2)、判断当前时间点是否需要升级飞机的级别。
3)、判断是否有飞机进入管制区。
这三件事情的先后顺序是根据题目的要求来的。
Java 超时
C++ AC
#include <stdio.h>#include <string.h>#include <queue>using namespace std;const int maxlen = 12;const int maxn = 202;const int maxTime = 24*60;struct Plane{ int time; char name[maxlen]; char level;};Plane planes[maxn];queue<Plane> queueArr[3];int n, hour, minute;int runArr[3]; int main(){ int i,j; while(scanf("%d", &n)!=EOF){ for(i = 0; i < n; i++){ scanf("%2d:%2d %s %c", &hour, &minute, planes[i].name, &planes[i].level); planes[i].time = hour * 60 + minute; } memset(runArr, 0, sizeof(runArr)); for(i = 0; i < 3; i++){ while(!queueArr[i].empty()){ queueArr[i].pop(); } } int curTime = planes[0].time; i = 0; for(; curTime < maxTime; curTime++){ hour = curTime / 60; minute = curTime % 60; int rank1 = -1; for(j = 0; j < 3; j++) { if(!queueArr[j].empty()){ rank1 = j; break; } } int rank2 = -1; for (j = 0; j < 3; j++) { if (runArr[j] <= curTime) { rank2 = j; break; } } if(rank1 != -1 && rank2 != -1){ Plane plane = queueArr[rank1].front(); queueArr[rank1].pop(); runArr[rank2] = curTime + 20; printf("%s,landing on runway %d.@%02d:%02d\n", plane.name, rank2+1, hour, minute); } if (curTime % 20 == 0) { if (!queueArr[1].empty()) { Plane plane = queueArr[1].front(); queueArr[1].pop(); plane.level = 'A'; plane.time = curTime; queueArr[0].push(plane); printf("%s,level up from B to A.@%02d:%02d\n", plane.name, hour, minute); } if (!queueArr[2].empty()) { Plane plane = queueArr[2].front(); queueArr[2].pop(); plane.level = 'B'; plane.time = curTime; queueArr[1].push(plane); printf("%s,level up from C to B.@%02d:%02d\n", plane.name, hour, minute); } } if (i < n && planes[i].time == curTime) { if (planes[i].level == 'A') { queueArr[0].push(planes[i]); } if (planes[i].level == 'B') { queueArr[1].push(planes[i]); } if (planes[i].level == 'C') { queueArr[2].push(planes[i]); } printf("hello %s.@%02d:%02d\n", planes[i].name, hour, minute); i++; } } } return 0;}/************************************************************** Problem: 1556 User: wzqwsrf Language: C++ Result: Accepted Time:50 ms Memory:1056 kb****************************************************************/5、题目1557:和谐答案
时间限制:3 秒内存限制:128 兆特殊判题:否提交:226解决:26
题目描述:
在初试即将开始的最后一段日子里,laxtc重点练习了英语阅读的第二部分,他发现了一个有意思的情况。
这部分的试题最终的答案总是如下形式的:
1.A;2.C;3.D;4.E;5.F。即共有六个空格,每个空格填入一个相应的字母代表这个空格他所选择的答案,且空格中的字母不存在重复。若每个空格选择的答案都是严格递增的,则laxtc认为这个答案是和谐的,如1.A;2.C;3.D;4.E;5.F;反之,若答案中存在不递增的情况,则他认为这组答案是不和谐的,如1.A;2.C;3.B;4.E;5.F;laxtc总是希望他所选择的答案是和谐的。由于laxtc的英语并不怎么好,所以他也经常会空着一些空格,如1.A2.;3.B;4.E;5.F;此时,只要排除掉空格后的剩余部分依然是递增的,那么laxtc也认为它是和谐的。
已知共有n个空格,laxtc已经为每一个空格选择好了Ci个候选对象。laxtc想知道他最多能填写几个空格,同时保持最终答案是和谐的。
输入:
输入包含多组测试数据。每组测试数据由一个整数n(1 <= n <= 100000)开头,表示共有n个位置。
接下来共有n行数字,第i行表示laxtc为第i个空格选择的候选答案(可能会有重复的答案)。由两部分组成。第一部分为一个整数t(1 <= t <= 5),表示该空格共有t个候选答案。第二部分为t个整数,代表laxtc为该空格选择的候选答案序号(由于题数过多,这里用数字代替字母,数字在int范围内)。
输出:
输出为一个整数,代表laxtc得到的最大和谐答案组的长度,长度即填写的空格数。
样例输入:
5
5 1 2 3 4 5
5 1 2 3 4 5
5 1 2 3 4 5
5 1 2 3 4 5
5 1 2 3 4 5
5
4 1 2 3 4
4 2 3 4 5
2 2 3
2 4 5
1 1
样例输出:
5
4
提示:
来源:
2014年王道论坛计算机考研机试全真模拟考试
解题思路:
这个题有点像LIS,但是好像又不太像。
其实整体上的思路并不是很复杂,但是比较难想,采用的还是动态规划的思想。
dp[i]表示的是第i个位置,所填写的答案,这个答案是在实时更新的。
举个例子说吧。
比如有以下样例输入
5
3 1 2 3
2 8 9
3 4 5 7
2 10 6
1 3
最初开始的时候,dp都为Integer.MAX_VALUE,以下展示dp变化。
dp[0] = 1;
dp[1] = 8;
dp[1] = 4;(这一步发现其实前面的位置可以输入的数字可以更小,所以就更新了dp[1]的值。)
dp[2] = 6;
dp[1] = 3;
最后的结果其实就是3。
每当输入一组候选答案的时候,找到每个候选答案在已选答案中的位置,如果有更小的答案可选择,就更新。如果发现可以拓展,就拓展答案的长度,最后就是结果。
C++ AC
#include <stdio.h>const int size = 5;int n,i,j;int array[size];int posArr[size];int colNum; int searchPosition(int *dp, int low, int high, int target) { int mid = 0; while (low <= high) { mid = (low + high) >> 1; if(dp[mid] == target){ return mid; } if(dp[mid] > target){ high = mid - 1; }else { low = mid + 1; } } return low;} int main(){ while(scanf("%d",&n) != EOF){ int *dp = new int[n]; for(i = 0; i < n; i++){ dp[i] = 10000000; } int low = 0; int high = 0; for(i = 0; i < n; i++){ scanf("%d",&colNum); for(j = 0; j < colNum; j++){ scanf("%d",&array[j]); posArr[j] = searchPosition(dp, low, high, array[j]); } for (j = 0; j < colNum; j++) { dp[posArr[j]] = dp[posArr[j]] < array[j] ? dp[posArr[j]] : array[j]; high = high > posArr[j] + 1 ? high : posArr[j] + 1; } } printf("%d\n",high); } return 0;} /************************************************************** Problem: 1557 User: wangzhenqing Language: C++ Result: Accepted Time:1400 ms Memory:2584 kb****************************************************************/Java AC
import java.io.BufferedReader;import java.io.InputStreamReader;import java.io.StreamTokenizer;import java.util.Arrays; public class Main { /* * 1557 */ public static void main(String[] args) throws Exception { StreamTokenizer st = new StreamTokenizer(new BufferedReader( new InputStreamReader(System.in))); while (st.nextToken() != StreamTokenizer.TT_EOF) { int n = (int) st.nval; int array[] = new int[5]; int posArr[] = new int[5]; int dp[] = new int[n]; Arrays.fill(dp, Integer.MAX_VALUE); int low = 0; int high = 0; for (int i = 0; i < n; i++) { st.nextToken(); int colNum = (int)st.nval; for (int j = 0; j < colNum; j++) { st.nextToken(); array[j] = (int)st.nval; posArr[j] = searchPosition(dp, low, high, array[j]); } for (int j = 0; j < colNum; j++) { dp[posArr[j]] = dp[posArr[j]] < array[j] ? dp[posArr[j]] : array[j]; high = high > posArr[j] + 1 ? high : posArr[j] + 1; } } System.out.println(high); } } private static int searchPosition(int[] dp, int low, int high, int target) { int mid = 0; while (low <= high) { mid = (low + high) >> 1; if(dp[mid] == target){ return mid; } if(dp[mid] > target){ high = mid - 1; }else { low = mid + 1; } } return low; }} /************************************************************** Problem: 1557 User: wangzhenqing Language: Java Result: Accepted Time:2320 ms Memory:26708 kb****************************************************************/
- 【九度】2014年王道论坛计算机考研机试全真模拟考试解题报告
- 2014年王道论坛计算机考研机试全真模拟考试
- 2014年王道论坛计算机考研机试全真模拟考试题目1:时钟
- 题目1494:Dota(2013年王道论坛计算机考研机试全真模拟考试)
- 【九度】2014年王道论坛研究生机试练习赛第二场解题报告
- 【九度】2014年王道论坛研究生机试练习赛第三场解题报告
- 9度-王道论坛计算机考研数据结构算法实战测试(1)
- 9度-王道论坛计算机考研数据结构算法实战测试(2)
- 9度-王道论坛计算机考研数据结构算法实战测试(3)
- 九度oj 2014年王道论坛研究生机试练习赛(二) 第四题
- 2017.9.22 模拟考试 解题报告
- 九度OJ解题报告
- 解题报告:九度1097
- 九度1184解题报告
- 九度1080解题报告
- 九度1019解题报告
- 九度1137解题报告
- 九度1139解题报告
- I - 0 or 1
- 数论进制水题
- gpio_test
- 基础知识(二)+ 寄存器(CPU工作原理)一
- [ACE源码分析]ACE_Reactor是如何做到事件分发的
- 【九度】2014年王道论坛计算机考研机试全真模拟考试解题报告
- ANSI转换到Unicode 或者将Unicode转换到ANSI
- VirtualBox下CentOS的网络配置
- 利用huson的日志获取编译错误信息的做法
- C++中的IO库(二)
- Dns解析为ip
- CSS布局:自适应高度的CSS布局
- 修改ZXing二维码扫描为竖屏模式
- 预处理的广搜