2013北邮计算机院上机题

A 日期
Description
请你计算出第X年Y月Z日是第X年的第几天。其中,1月1日是第一天,1月2日是第二天,以此类推。
计算时请注意闰年的影响。对于非整百年,年数能整除4是闰年,否则不是闰年;对于整百年,年数能整除400是闰年,否则不是闰年。如1900年和1901年不是闰年,而2000年和2004年是闰年。
InputFormat
第一行有一个整数T(T <= 100),表示一共有T组数据需要你处理。
接下来一共有T行,每行是一个如下格式的字符串:X:Y:Z,表示你需要计算第X年Y月Z日是第X年的第几天。其中X是一个大于0,小于2100的整数。保证字符串的格式都是合法的,字符串所表示的日期也都是存在的。
OutputFormat
对于每组数据,你需要输出一个整数,表示所求得的结果。
SampleInput
2
2013:4:12
112:4:12
SampleOutput
102
103
  思路:王道机试指南上的模板题。

#include
#include
#include<string.h>

#define ISLEAPYEAR(x) x % 100 != 0 && x % 4 == 0 || x % 400 == 0 ? 1 : 0

int dayOfMonth[13][2] = {
    0,0,
    31,31,
    28,29,
    31,31,
    30,30,
    31,31,
    30,30,
    31,31,
    31,31,
    30,30,
    31,31,
    30,30,
    31,31
};

struct Date {
    int year;
    int month;
    int day;
    void nextDay() {
        day++;
        if(day > dayOfMonth[month][ISLEAPYEAR(year)]) {
            day = 1;
            month++;
            if(month > 12) {
                month = 1;
                year++;
            }
        }
    }
};

int buf[5001][13][32];

int main() { 
    Date temp;
    temp.year = 0;
    temp.month = 1;
    temp.day = 1;
    int count = 0;
    while(temp.year <= 5000) {
        buf[temp.year][temp.month][temp.day] = count;
        temp.nextDay();
        count++;
    }

    int y1,m1,d1,y2,m2,d2;
    int T;
    scanf("%d",&T);
    while(T--) { 
        scanf("%d:%d:%d",&y1,&m1,&d1);
        printf("%d\n",buf[y1][m1][d1] - buf[y1][1][1] + 1);
    }  
} 

B 统计节点个数
Description
给出一棵有向树,一共有N (1< N ≤ 1000 )个节点,如果一个节点的度(入度+出度)不小于它所有儿子以及它父亲的度(如果存在父亲或儿子),那么我们称这个节点为p节点,现在你的任务是统计p节点的个数。
InputFormat
第一行为数据组数T (1≤T≤100 )。
每组数据第一行为N 表示树的节点数。后面为N−1 行,每行两个数x ,y (0 ≤ x,y < N),代表y是x的儿子节点。
OutputFormat
每组数据输出一行,为一个整数,代表这棵树上p节点的个数。
SampleInput
2
5
0 1
1 2
2 3
3 4
3
0 2
0 1
SampleOutput
3
1
Hint
第一组的p节点为1,2,3;第二组的p节点为0。
  思路:树就是图嘛,先把图中每个节点的度算出来,然后和它的邻接节点比较就可以了。

#include
#include
#include

using namespace std;

int main() {
    int T;
    scanf("%d",&T);
    vector<int> a[1000];
    int b[1000];
    while(T--) {       
        int N;
        scanf("%d",&N);
        for(int i = 0;i < N;i++) {
            a[i].clear();
        }
        memset(b,0,sizeof(b));
        int x,y;
        for(int i = 0;i < N - 1;i++) {
            scanf("%d%d",&x,&y);
            a[x].push_back(y);
            a[y].push_back(x);
            b[x]++;
            b[y]++;
        }
        int num = 0;
        bool flag;
        for(int i = 0;i < N;i++) {
            flag = true;
            for(int j = 0;j < a[i].size();j++) {
                if(b[i] < b[a[i][j]]) {
                    flag = false;
                    break;
                }
            }
            if(flag) {
                num++;
            }
        }
        printf("%d\n",num);
    }
}

C 中序遍历序列

Description

给出一个序列,判断该序列是不是某二叉搜索树的中序遍历序列,如果是输出”Yes”,否则输出”No”。

一颗带权二叉树是一颗二叉搜索树(二叉排序树),当且仅当对于任意一个节点,他的左子树中的所有权值小于当前节点的权值,且它的右子树中的所有权值均大于当前节点的权值。

Input Format

第一行T (T<=10 )代表数据组数。

每组数据包括两行:

第一行为一个整数N (1<=N<=400),表示序列的长度。

第二行包含N 个整数,表示这个这个序列,序列中的数的x 范围为(1<=x<=100000)。

OutPut Format

每组数据,如果是二叉搜索树的中序遍历序列输出”Yes”,否则输出”No”。

Input
2
4
1 2 3 4
4
1 3 2 4

OutPut
Yes
No
  思路:这题放在C题感觉好水啊,只要判断一个序列是不是严格递增的就行了。。。

#include

int main() {
    int T;
    scanf("%d",&T);
    while(T--) {
        int N;
        scanf("%d",&N);
        int x,y;
        N--;
        scanf("%d",&x);
        y = x;
        bool flag = false;
        while(N--) {
            scanf("%d",&x);
            if(!flag && y >= x) {
                flag = true;               
            }
            y = x;
        }
        if(flag) {
            printf("No\n");
        } else {
            printf("Yes\n");
        }
    }
}

D 最小距离查询

Description

给定一个由小写字母a到z组成的字符串S,其中第i个字符为S[i](下标从0开始)。你需要完成下面两个操作:

INSERT c

其中c是一个待输入的字符。你需要在字符串的末尾添加这个字符。保证输入的字符同样是a到z之间的一个小写字母。

QUERY x

其中x是一个输入的整数下标。对于这个询问,你需要回答在S当中和S[x]相等且与x最近的距离。输入保证x在当前字符串中合法。

例如S = “abcaba”,如果我们操作:
INSERT a

则在S的末端加一个字符a,S变成”abcabaa”。

接下来操作
QUERY 0

由于S[0] = a,在S中出现的离他最近的a在下标为3的位置上,距离为3 - 0 = 3。因此应当输出3。

接下来,如果
QUERY 4

S[4] = b,S中离它最近的b出现在下标为1处,距离为4 - 1 = 3。同样应当输出3。

给定初始字符串S和若干操作,对于每个QUERY,你需要求出相应的距离。

InputFormat

输入的第一行是一个正整数T (T≤20 ),表示测试数据的组数。

每组输入数据的第一行是一个初始串S。第二行是一个正整数m (1≤m≤100000 ),表示总共操作的数量。接下来m行,每行表示一个操作。操作的格式如上所述。

数据保证在任何情况下,S的长度不会超过100000。

OutputFormat

对于每个QUERY,输出所求的最小距离。如果S中其它位置都不存在和它相同的字符,输出-1。

SampleInput
2
axb
3
INSERT a
QUERY 0
QUERY 1
explore
3
INSERT r
QUERY 7
QUERY 1

SampleOutput
3
-1
2
-1

Hint

由于输入数据较大,C/C++中推荐使用scanf进行读入以获得更快的读入速度。同时请注意算法复杂度。

  思路:以后有时间再做吧。。。

你可能感兴趣的:(北邮OJ(各学院机试题))