2013北邮网研院上机题

Problem A 最值问题
时间限制 1000 ms 内存限制 65536 KB
题目描述
给出N个数,求出这N个数中最大值和次大值。注意这里的次大值必须严格小于最大值。输入保证N个数中至少存在两个不同的数。
输入格式
第一行为测试数据的组数T(T≤20)。请注意,任意两组测试数据之间是相互独立的。
每组数据包括两行:
第一行为一个整数N(1≤N≤1000)。
第二行为N个正整数,每个整数均不大于106。

输出格式
每组数据输出两个数,即N个数的最大值和次大值,中间用空格隔开。

输入样例
2
5
1 2 3 4 5
4
2 2 2 3
输出样例
5 4
3 2
  思路:没必要开数组,边读取边判断

#include<stdio.h>

int main() {
    int T;
    scanf("%d",&T);
    while(T--) {
        int N;
        int a,b = 0,t;
        scanf("%d%d",&N,&a);
        while(--N) {
            scanf("%d",&t);
            if(t > a) {
                b = a;
                a = t;
            } else {
                if(t > b) {
                    b = t;
                }
            }
        }
        printf("%d %d\n",a,b);  
    }   
}

Problem B 统计时间间隔
时间限制 1000 ms 内存限制 65536 KB
题目描述
给出两个时间(24小时制),求第一个时间至少要经过多久才能到达第二个时间。给出的时间一定满足的形式,其中x和y分别代表小时和分钟。0≤x<24,0≤y<60。
输入格式
第一行为数据组数T(1≤T≤50000)。
每组数据包括两行,分别代表两个时间

输出格式
每组数据输出一行,表示最少经过的分钟数。

输入样例
2
7:00
7:00
7:00
8:00
输出样例
0
60
  思路:小学数学题。

#include<stdio.h>

int main() {
    int T;
    scanf("%d",&T);
    while(T--) {
        int x1,y1,x2,y2;
        scanf("%d:%d",&x1,&y1);
        scanf("%d:%d",&x2,&y2);
        int t1 = x1 * 60 + y1;
        int t2 = x2 * 60 + y2;
        if(t2 >= t1) {
            printf("%d\n",t2 - t1);
        } else {
            printf("%d\n",24 * 60 - (t1 - t2));
        }       
    }
}

Problem C.字符串转换
时间限制 1000 ms 内存限制 65536 KB
题目描述
我们将仅由若干个同一小写字母构成的字符串称之为简单串,例如”aaaa”是一个简单串,而”abcd”则不是简单串。现在给你一个仅由小写字母组成的字符串,你需要用最小的花费,将其转换成一个简单串。 花费的计算规则如下:将a到z这26个小写字母从左到右排成一排,则每个字母都有左右两个邻居,我们认为a的左邻居是z,z的右邻居是a。一个字母只能转换成其相邻的字母,转换的花费为1。一个字母可以进行多次转换,例如将a转换成d,可以进行如下的步骤: a->b->c->d,花费为3。字符串的转换花费为所有字母转换花费之和。例如将字符串”abbbz”转换成简单串的最小花费为3,转换后的结果为”bbbbb”。

输入格式
第一行一个整数T(T≤100),表示测试数据的组数。 每组测试数据只有一行,为仅含小写字母的字符串,字符串长度不超过1000。

输出格式
对于每一组数据,输出一个整数,表示将字符串转换成简单串的最小花费。

输入样例
2
abbba
abbac
输出样例
2
3
  思路:26个字母量不大,直接暴力遍历所有情况。

#include<stdio.h>
#include<string.h>
#include<stdlib.h>

int main() {
    int a[26];
    int T;
    scanf("%d",&T);
    getchar();//
    while(T--) {
        memset(a,0,sizeof(a));

        char ch;
        while((ch = getchar()) && ch != '\r') {
            a[ch - 'a']++;
        }

//      char ch[1000];
//      scanf("%s",ch);
//      for(int i = 0;ch[i];i++) a[ch[i] - 'a']++;  

        int SUM = 2000000000,sum,t;     
        for(int i = 0;i < 26;i++) {
            if(a[i]) {
                sum = 0;
                for(int j = 0;j < 26;j++) {
                    if(a[j]) {
                        t = abs(j - i);                         
                        if(t <= 13) {
                            sum += t * a[j];
                        } else {
                            sum += (26 - t) * a[j];
                        }
                    }                   
                }
                if(sum < SUM) {
                    SUM = sum;
                }       
            }       
        }           
        printf("%d\n",SUM);
    }
}

Problem D.文件系统
题目描述
现在很多操作系统的文件系统都是基于树形结构设计的。即一个目录下可以有若干个目录和文件,而每个目录和文件都可以通过一条从根目录出发的唯一路径来唯一确定。我们希望你实现对这样的一个文件系统的简单管理。
为了简化问题,我们做出如下假设:
假设文件系统初始时只有一个根目录root。
假设所有出现的文件和目录的名字都是唯一的。即,不会有两个相同名字的文件出现,不会有两个相同名字的目录出现,也不会有一个文件和一个目录名字相同。
文件名字和目录名字都是长度在1到20之间的字符串(包括1和20),且只由英文大写字母、英文小写字母、数字组成。大小写字母之间不等效。
你需要实现如下操作:
CREATEFILE FILENAME DIRNAME
这个操作的含义是:在DIRNAME的目录下创建一个名字为FILENAME的文件。我们保证当出现这个操作时,DIRNAME是一个已经存在的目录,而FILENAME这个名字是首次出现。
CREATEDIR DIRNAME1 DIRNAME2 这个操作的含义是:在DIRNAME2的目录下创建一个名字为DIRNAME1的目录。我们保证当出现这个操作时,DIRNAME2是一个已经存在的目录,而DIRNAME1这个名字是首次出现。
LISTFILE DIRNAME 这个操作的含义是:按照创建的先后顺序打印出DIRNAME目录下的所有文件名字。我们保证当出现这个操作时,DIRNAME是一个已经存在的目录.
LISTDIR DIRNAME 这个操作的含义是:按照创建的先后顺序打印出DIRNAME目录下的所有目录名字。我们保证当出现这个操作时,DIRNAME是一个已经存在的目录

输入格式
第一行有一个整数T,表示一共有T(T≤20)组数据需要你处理。请注意各组数据之间是相互独立的。每当处理新的一组数据时,你都应当假设此时只有一个名字为root的根目录存在。
对于每组数据,第一行有一个整数N(0< N≤100),表示有N个操作需要你处理,接下来的N行,每一个行描述了一个操作。

输出格式
对于每个LISTFILE操作和LISTDIR操作,如果找到了X个文件(或目录),你需要输出X行,按照创建时间从早到晚的顺序,每一行打印一个文件(或目录)的名字。如果找到了0个文件(或目录),就不要输出任何东西。请注意不要输出多余的空格和换行符。

输入样例
2
8
CREATEFILE desktop root
CREATEDIR DESKTOP root
LISTFILE root
LISTDIR DESKTOP
CREATEFILE scr20130412 DESKTOP
CREATEFILE scr20130411 DESKTOP
CREATEFILE scr20130413 DESKTOP
LISTFILE DESKTOP
5
LISTFILE root
CREATEDIR webapp root
CREATEDIR myweb webapp
CREATEDIR MyWeb webapp
LISTDIR webapp
输出样例
desktop
scr20130412
scr20130411
scr20130413
myweb
MyWeb

  思路:树的存储结构我用的是孩子兄弟,遍历就和二叉树一样了。

#include<stdio.h>
#include<string.h>
#include<stack>

using namespace std; 

struct TreeNode {
    char name[21];
    bool flag;
    TreeNode *firstChild;
    TreeNode *nextSibling; 
}tree[105];

int loc;

TreeNode *create() {
    tree[loc].firstChild = tree[loc].nextSibling = NULL;
    return &tree[loc++];
}

//TreeNode *preRootTraverse(TreeNode *root,char name[]) {       
//  if(root) {
//      if(!strcmp(root->name,name)) {
//          return root;
//      } else {
//          TreeNode *temp = preRootTraverse(root->firstChild,name);            
//          if(temp) {
//              return temp;
//          } else {
//              temp = preRootTraverse(root->nextSibling,name); 
//              if(temp) {
//                  return temp;
//              }
//          }
//      } 
//  } else {
//      return NULL;
//  }   
//}

TreeNode *preRootTraverse(TreeNode *root,char name[]) {
    stack<TreeNode *> s;
    TreeNode *p = root;
    while(p != NULL || !s.empty()) {
        while(p != NULL) {
            if(!strcmp(p->name,name)) {
                return p;
            } else {
                s.push(p);
                p = p->firstChild;
            }
        }
        if(!s.empty()) {
            p = s.top();
            s.pop();
            p = p->nextSibling;
        }
    }
}

void add(TreeNode *tempRoot,TreeNode *newFileOrDir) {
    if(tempRoot->firstChild == NULL) {
        tempRoot->firstChild = newFileOrDir;
    } else {
        tempRoot = tempRoot->firstChild;
        while(tempRoot->nextSibling != NULL) {
            tempRoot = tempRoot->nextSibling;
        }
        tempRoot->nextSibling = newFileOrDir;
    }
}

void listFileOrDir(TreeNode *tempRoot,bool _flag) {     
    if(tempRoot->firstChild != NULL) {
        if(tempRoot->firstChild->flag == _flag) {
            printf("%s\n",tempRoot->firstChild->name);
        }   
        tempRoot = tempRoot->firstChild;
        while(tempRoot->nextSibling != NULL) {
            if(tempRoot->nextSibling->flag == _flag) {
                printf("%s\n",tempRoot->nextSibling);
            }       
            tempRoot = tempRoot->nextSibling;
        }
    }
}

int main() {
    int T;
    scanf("%d",&T); 
    while(T--) {
        loc = 0;    
        TreeNode *root = create();
        root->flag = false;
        strcpy(root->name,"root");      
        int N;
        scanf("%d",&N);
        while(N--) {
            char cmd[11],tempRootName[21];
            scanf("%s",cmd);
            if(!strcmp(cmd,"CREATEFILE")) {
                TreeNode *newFile = create();   
                newFile->flag = true;       
                scanf("%s%s",newFile->name,tempRootName);
                TreeNode *tempRoot = preRootTraverse(root,tempRootName);
                add(tempRoot,newFile);
            } else {
                if(!strcmp(cmd,"CREATEDIR")) {
                    TreeNode *newDir = create();    
                    newDir->flag = false;       
                    scanf("%s%s",newDir->name,tempRootName);
                    TreeNode *tempRoot = preRootTraverse(root,tempRootName);
                    add(tempRoot,newDir);                   
                } else {
                    if(!strcmp(cmd,"LISTFILE")) {   
                        scanf("%s",tempRootName);
                        TreeNode *tempRoot = preRootTraverse(root,tempRootName);
                        listFileOrDir(tempRoot,true);
                    } else {
                        scanf("%s",tempRootName);                               
                        TreeNode *tempRoot = preRootTraverse(root,tempRootName);    
                        listFileOrDir(tempRoot,false);
                    }
                }
            }
        }               
    }
}
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值