時間限制: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
****************************************************************/