【九度】2014年王道论坛计算机考研机试全真模拟考试解题报告

来源:互联网 发布:薄层层析硅胶板 淘宝 编辑:程序博客网 时间:2024/05/17 22:49
1、题目1553:时钟
时间限制: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****************************************************************/


0 0
原创粉丝点击