2011年北邮网研院复试上机题目

2011.网研院.Problem A.字符串操作

链接1: http://10.105.242.83/problem/140 链接2: http://10.105.242.80/problem/p/107

Description
大家平时都会用到字符串,现在有几种字符串操作,需要你用这几种操作处理下字符串。
Input
多组数据,以EOF结束。
第一行一个字符串,字符串长度大于0,并且小于等于200。
第二行一个数字t,(0<t<=200)。
下面t行,每行表示一种操作。
共有两种操作,每行数据的第一个数表示操作的种类:
翻转操作:第一个是一个数字0,然后两个数字i和len,翻转从下标i长度为len的子串。
替换操作:第一个是一个数字1,然后两个数字i和len,接着一个长度为len的字符串str,用str替换从下标i长度为len的子串。
字符串操作后会更新,旧的字符串被舍弃。(详见sample)
Output
每个操作之后输出生成的新的字符串
Sample Input

bac
2
0 0 3
1 1 2 as

Sample Output

cab
cas

Hint
字符串下标从0开始,所有操作的数据范围都合乎规范。
代码

#include <iostream>
#include <algorithm>
using namespace std;

int main()
{
    string str;
    int n;
    int num1, num2, num3;
    string str2;
    while(cin >> str)
    {
        cin >> n;
        while( n-- )
        {
            cin >> num1 >> num2 >> num3;
            if( num1 == 0 )
                reverse( str.begin()+ num2, str.begin()+num2+num3 );
            else
            {
                cin >> str2;
                str.erase( num2, num3 );
                str.insert( num2, str2 );
            }
            cout << str << endl;
        }
    }
    return 0;
}
2011.网研院.Problem B.虚数

链接1: http://10.105.242.83/problem/141 链接2: http://10.105.242.80/problem/p/108
链接3: 牛客网 - 虚数

Description
给你一个复数集合{Aj+i*Bj},保证Aj和Bj都是整数,初始为空集。
每次会给你如下两种操作中的一种:
1.“Insert x+iy”,其中x,y都是整数。表示在集合中加入一个复数 x+iy,同时输出此时集合的大小;
2.“Pop”。如果集合为空集直接返回“Empty!”,如果有元素则以"x+iy"的形式显示集合中模值最大的复数,然后将该元素从集合中删除,之后在第二行显示操作之后的集合大小,如果为空集则显示“Empty!”。
Input
第一行只有一个数T,代表case数。0<=T<=10
每一组case:
第一行有一个整数n,表示这组case中一共有n条命令 0<n<=100
接下来n行每行有一个命令,命令如上所述
保证不会输入两个模值同样的元素,并保证实部虚部都大于0,小于1000。
Output
依照上述原则输出每一个命令对应的输出
如果输入命令是Insert命令,则对应的输出占一行为集合大小;
如果输入命令是Pop命令,则对应的输出占一行或者两行,为模值最大的复数和集合大小。
请注意,输出集合大小的格式为"Size:空格x回车",x为集合大小
Sample Input

1
5
Pop
Insert 1+i2
Insert 2+i3
Pop
Pop

Sample Output

Empty!
Size: 1
Size: 2
2+i3
Size: 1
1+i2
Empty!

代码

#include <cstdio>
#include <algorithm>
#include <queue>
#include <cstring>
#include <cmath>

using namespace std;

struct complex
{
    int real;
    int imaginary;
    double module;
    friend bool operator < ( complex a, complex b )
    {
        return a.module < b.module;
    }
};

int main()
{
    int T, n;
    scanf( "%d", &T );
    char demand[8];
    priority_queue<complex> cset;
    complex temp;
    while( T-- )
    {
        while( cset.size() )
            cset.pop();
        scanf("%d", &n);
        while( n-- )
        {
            scanf("%s", demand);
            if( !strcmp(demand, "Insert") )
            {
                scanf("%d+i%d", &temp.real, &temp.imaginary );
                temp.module = sqrt(1.0*temp.real*temp.real + temp.imaginary*temp.imaginary );
                cset.push( temp );
                printf("Size: %d\n", cset.size());
            }
            else if( !strcmp(demand, "Pop") )
            {
                if( !cset.size() )
                    printf("Empty!\n");
                else
                {
                    temp = cset.top();
                    cset.pop();
                    printf("%d+i%d\n", temp.real, temp.imaginary );
                    if( !cset.size() )
                        printf("Empty!\n");
                    else
                        printf("Size: %d\n", cset.size());
                }
            }
        }
    }
    return 0;
}
2011.网研院.Problem C.中序遍历树

链接1: http://10.105.242.83/problem/142 链接2: http://10.105.242.80/problem/p/109
Description
给一棵树,你可以把其中任意一个节点作为根节点。每个节点都有一个小写字母,中序遍历,得到一个字符串,求所有能得到的字符串的字典序最小串。因为这棵树不一定是二叉树,所以中序遍历时,先中序遍历以节点序号最小的节点为根的子树,然后再遍历根节点,最后根据节点序号从小到大依次中序遍历剩下的子树。
Input
多组数据,以EOF结束。
第一行一个数n(0<n<=100),表示树的节点的个数,节点从0开始。
然后一个长度为n的串,第i(0<=i<n)个字符表示节点i的字符。 接下来n-1行,每行两个数a,b,(0<=a,b<n),表示a和b之间有一条无向边。
Output
题中要求的最小的字符串
Sample Input

3
bac
0 1
1 2
4
abcd
0 1
0 2
0 3

Sample Output

bac
bacd

Hint
意思就是请枚举所有的点为根,然后中序遍历
最后输出所有结果中字典序最小的
比如说第二组数据
以0为根时结果为 bacd
以1为根时结果为 cadb
以2为根时结果为 badc
以3为根时结果为 bacd
所以字典序最小的是bacd
代码

#include <iostream>
#include <vector>

using namespace std;

const int maxsize = 26;

string data;    //节点数据
string path;
string temp;
vector<int> vertex[maxsize];
int numNode = 0;

bool visit[maxsize] = {false};
void inorder( int root )
{
    visit[root] = true;
    int i;
    for( i = 0; i < vertex[root].size(); i++ )  // 找到第一个未被标记的孩子 即为左子树 遍历玩此左子树 就推出循环
    {
        int lc = vertex[root][i];
        if( !visit[lc] )
        {
            inorder( lc );
            break;
        }
    }
    temp.push_back( data[root] );               //访问根节点
    int sonsize = vertex[root].size();
    for( i = i+1; i < sonsize; i++ )            //上述 i 指向第一个左孩子 接下来依次遍历每个右孩子
    {
        int rc = vertex[root][i];
        if( !visit[rc] )
            inorder( rc );
    }
}

int main()
{
    while( cin >> numNode )
    {
        for( int i = 0; i < numNode; i++ )
            vertex[i].clear();
        data.clear();
        temp.clear();
        path.clear();

        cin >> data;
        int i, u, v;
        for( i = 0; i < numNode-1; i++ )
        {
            cin >> u >> v;
            vertex[u].push_back( v );
            vertex[v].push_back( u );
        }
        for( int i = 0; i < numNode; i++ )
        {
            sort( vertex[i].begin(),  vertex[i].end() );
        }
        memset( visit, false, maxsize );
        inorder(0);
        path = temp;
        for( i = 1; i < numNode; i++ )
        {
            memset( visit, false, maxsize );
            temp.clear();
            inorder( i );
            if( temp < path )
                path = temp;
        }
        cout << path << endl;
    }
    return 0;
}
2011.网研院.Problem D.first集

链接1: http://10.105.242.83/problem/143 链接2: http://10.105.242.80/problem/p/110
Description
对于文法,给出求first集的算法,让大家求first集。输入中大写字母表示非终结符,小写字母表示终结符,#表示空也是终结符。
First集求解算法如下:
为了求每个符号的first集,连续使用以下规则,直到每个符号的first集不再增大为止。
1.对于终结符,它的first集就是它自己。
2.对于非终结符,如果有产生式 X -> a… ,把a加入first(X)中,
如果X-># ,即X可以推出空,那么把空加入first(X)中。
3.对于X->Y… 这样的产生式,且X,Y都是非终结符,把first(Y)中的所有非空的元素加入到first(X)中。
对于X->Y1Y2…Yk产生式,X,Y1,Y2…Yk都是非终结符,对于某个i(i<=k),如果first(Y1),first(Y2),…first(Yi-1) 都含有空,那么将first(Yi)中的所有非空元素加入到first(X)中。若所有的first(Yi)(i=1,2,…k)中都有空,那么将空加入first(X)中。
Input
多组数据,以EOF结束。
第一行一个数字n,表示有n个文法式,(0<n<=10)。
下面n行,每行第一个是一个大写字母,表示产生式的左边,然后一个字符串,由大写字母(非终结符),小写字母(终结符)和#(空)组成。
Output
按照字典序输出每个非终结符的first(集)。
每行表示一个first集。第一个字母输出表示非终结符(按字母序排列),然后按字母顺序输出first集,如果包含空的话,最后输出#。一行中每两个字符间有一个空格。
Sample Input

4
B A
A ab
A c
A #

Sample Output

A a c #
B a c #

Hint

思路
欣赏一下题目就行了,这题据说当年打比赛拿奖的出题人都未能在规定时间做出来,我等渣渣看看题目就好。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值