2018年北京信息科技大学第十届程序设计竞赛暨ACM选拔赛

链接:https://www.nowcoder.com/acm/contest/118/A
来源:牛客网

PUBG
时间限制:C/C++ 1秒,其他语言2秒
空间限制:C/C++ 32768K,其他语言65536K
64bit IO Format: %lld

题目描述

最近,喜爱ACM的PBY同学沉迷吃鸡,无法自拔,于是又来到了熟悉的ERANGEL。经过一番搜寻,PBY同学准备动身前往安全区,但是,地图中埋伏了许多LYB,PBY的枪法很差,希望你能够帮他找到一条路线,每次只能向上、下、左、右移动,尽可能遇到较少的敌人。

输入描述:

题目包含多组测试,请处理到文件结束;
第一行是一个整数n,代表地图的大小;
接下来的n行中,每行包含n个整数a,每个数字a代表当前位置敌人的数量;
1 < n <= 100,1 <= a <= 100,-1代表当前位置,-2代表安全区。

输出描述:

对于每组测试数据,请输出从当前位置到安全区所遇到最少的敌人数量,每个输出占一行。
示例1

输入

5
6 6 0 -2 3
4 2 1 2 1
2 2 8 9 7
8 1 2 1 -1
9 7 2 1 2

输出

9
示例2

输入

5
62 33 18 -2 85
85 73 69 59 83
44 38 84 96 55
-1 11 90 34 50
19 73 45 53 95

输出

173

思想:广搜+优先队列
  
代码:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
#include<bits/stdc++.h>
using namespace std;
int start_x,start_y,end_x,end_y;
struct p{
    int a;
    int b;
    int count;
    friend bool operator <(p x,p y){
        return x.count>y.count;
    }
};
int n;
int mp[105][105];
int bfs();
int main(){
    while(~scanf("%d",&n)){
        for(int i=0;i<n;i++){
            for(int j=0;j<n;j++){
                scanf("%d",&mp[i][j]);
                if(mp[i][j]==-1){
                    start_x=i;
                    start_y=j;
                }
                if(mp[i][j]==-2){
                    end_x=i;
                    end_y=j;
                }
            }
        }
        int bu=bfs();
        printf("%d\n",bu);
    }
}
int fang[4][2]={1,0,0,1,-1,0,0,-1};
int vis[105][105];
int go(int xx,int y);
int bfs(){
    priority_queue<p> q;
    memset(vis,0,sizeof(vis));
    p t;
    t.a=start_x;
    t.b=start_y;
    t.count=0;
    vis[t.a][t.b]=1;
    q.push(t);
    while(!q.empty()){
        p d=q.top();
        q.pop();
        vis[d.a][d.b]=1;
        for(int i=0;i<4;i++){
            int xx=d.a+fang[i][0];
            int yy=d.b+fang[i][1];
            if(go(xx,yy)){
                if(xx==end_x&&yy==end_y){
                    return d.count;
                }
                else{
                    p next;
                    next.a=xx;
                    next.b=yy;
                    next.count=d.count+mp[xx][yy];
                    q.push(next);
                }
            }
        }
    }
    return 0;
}
int go(int xx,int yy){
    if(xx>=0&&xx<n&&yy>=0&&yy<n&&!vis[xx][yy])
        return 1;
    return 0;
}

链接:https://www.nowcoder.com/acm/contest/118/B
来源:牛客网

precise math function
时间限制:C/C++ 1秒,其他语言2秒
空间限制:C/C++ 32768K,其他语言65536K
64bit IO Format: %lld

题目描述

喜爱ACM的PBY同学遇到了一道数学难题,已知底数n,请你帮他准确的计算出结果a = nπ(n的π次方),结果保留小数点后x位。

输入描述:

第一行是一个整数t,表示测试实例的个数;
然后是t行输入数据,每行包含两个正整数n和x,表示底数和保留位数。
(1 <= t <= 100,1 <= n <= 500,1 <= x <= 6)

输出描述:

对于每组输入数据,分别输出结果a,每个输出占一行。
示例1

输入

3
1 3
7 6
9 1

输出

1.000
451.807873
995.0
思路:水题,主要难在输出;
代码:
1
2
3
4
5
6
7
8
9
10
11
12
13
#include<bits/stdc++.h>
using namespace std;
const double pi=acos(-1);
int main(){
    int T;
    scanf("%d",&T);
    while(T--){
        int n,x;
        scanf("%d%d",&n,&x);
        double sum=pow(n,pi);
        printf("%.*lf\n",x,sum);
    }
}

链接:https://www.nowcoder.com/acm/contest/118/D
来源:牛客网

打篮球
时间限制:C/C++ 1秒,其他语言2秒
空间限制:C/C++ 32768K,其他语言65536K
64bit IO Format: %lld

题目描述


1, 2, 3在打篮球, 可是二打一总是不公平的, 于是他们决定一对一,另一个人在边上看着, 谁输了谁就和下场和在边上看着的那个人交换。 现在给你一个胜利者的序列(每一轮胜利的人), 问这个序列合不合法。(一开始1,2单挑, 3在下面看着)

输入描述:

第一个数是数字n(1<=n<=100), 代表输入的胜利者序列的规模, 接下来的n行描述了胜利者序列。第i行包含一个正整数a[i],(1<=a[i]<=3),代表着a[i]赢得比赛

输出描述:

输出YES如果胜利者序列合法, 否则NO
示例1

输入

3
1
1
2
2
1
2

输出

YES
NO

说明

第一个例子中, 1赢了2, 3代替2; 1赢了3, 2代替3; 2赢了
第二个例子中, 1赢了2, 3代替2, 这时候2明显已经在场下了故不可能为胜利者
思路:模拟;
代码:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
#include<bits/stdc++.h>
using namespace std;
int main(){
    int n;
    while(~scanf("%d",&n)){
        int flag=0;
        int x=1,y=2;
        int deng=3;
        for(int i=0;i<n;i++){
            int a;
            scanf("%d",&a);
            if(flag) continue;
            if(x==a){
                y=deng^y;
                deng=y^deng;
                y=y^deng;
            }
            else if(y==a){
                x=deng^x;
                deng=x^deng;
                x=x^deng;
            }
            else
                flag=1;
        }
        if(flag) printf("NO\n");
        else printf("YES\n");
    }
}

链接:https://www.nowcoder.com/acm/contest/118/E
来源:牛客网

233
时间限制:C/C++ 1秒,其他语言2秒
空间限制:C/C++ 32768K,其他语言65536K
64bit IO Format: %lld

题目描述


Kirai聊天的时候非常喜欢发“233”,“233”来源于猫扑表情第233号,是一张捶地大笑的表情。
Kirai每当看到很好玩的消息的时候总会回一串“2333...”。
Kirai其实十分高冷,他发现了这个问题。为了不希望别人立刻知道他在笑,他决定将两个“233..”乘在一起发出去。

输入描述:

输入样例有多组,全部是正整数。首先输入样例组数T(T≤1500)。
接下来输入T组数,每组数字由两个233串组成,每个233串长度3≤n≤50。
数据保证每个233串必然会有一个2作为开头,并且3的数量≥2。

输出描述:

两个233串的乘积。
示例1

输入

2
233 233
23333333333333333333333333333333333333333333333333 23333333333333333333333333333333333333333333333333

输出

54289
544444444444444444444444444444444444444444444444428888888888888888888888888888888888888888888888889
思想:用java写的话,就是水题;
代码:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
import java.util.Scanner;
import java.math.BigInteger;
public class Main {
    public static void main(String[] arge){
        Scanner cin=new Scanner(System.in);
        int T=cin.nextInt();
        for(int i=0;i<T;i++){
            BigInteger a=cin.nextBigInteger();
            BigInteger b=cin.nextBigInteger();
            BigInteger sum=a.multiply(b);;
            System.out.println(sum);
        }
    }
}

链接:https://www.nowcoder.com/acm/contest/118/F
来源:牛客网

扫雷
时间限制:C/C++ 1秒,其他语言2秒
空间限制:C/C++ 32768K,其他语言65536K
64bit IO Format: %lld

题目描述


《扫雷》是一款大众类的益智小游戏,于1992年发行。游戏目标是在最短的时间内根据点击格子出现的数字找出所有非雷格子,同时避免踩雷,踩到一个雷即全盘皆输。当某个位置为数字的时,代表它周围的八连通区域中有对应数量的雷。
kirai获取了简化版扫雷(没有标记雷的小旗)的后台数据(后台数据包括所有数字和雷的位置),转换为一个n*m(1≤n, m≤500)的矩阵并对格子类型做了如下标记:
雷被标记为'*';
点开的空白区域标记为'0';
未点开的空白区域标记为'.';
数字1~8代表周围有多少雷;
kirai非常笨,他希望你帮他完成这样的任务:
给定k(1≤k≤min(可扫位置数, 10))个位置坐标和扫雷游戏的后台数据,输出点开指定位置序列后游戏的结果,初始时游戏中没有点开任何位置。
注:数据保证扫雷过程中不会重复点击已扫位置。

输入描述:

输入样例有多组,全部是正整数。首先输入样例组数T(T≤10)。
接下来输入T组数,每组数据第一行包括四个正整数n,m,k(1≤n, m≤500, 1≤k≤min(可扫位置数, 10))分别表示地图的行、列数和即将点开的位置数。紧接着是一个n*m的矩阵,代表扫雷的后台数据,。
矩阵后是k个整数对x
i
, y
i
(1≤i≤k, 1≤x
i
≤n, 1≤y
i
≤m),表示依次点开的位置。

输出描述:

如果某一步踩到雷,输出"Game over in step x"(不包括引号",表示第x步踩中雷);未踩到雷则根据扫雷的游戏规则更新,并输出最后一步结束后显示给kirai的矩阵。
示例1

输入

1
5 5 3
2*11*
*2111
22...
*1...
11...
1 1
3 3
1 2

输出

Game over in step 3

说明

2....
.....
.....
.....
.....
2....
.2111
.2000
.1000
.1000
Game over in step 3
思路:水,模拟;
代码:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
#include<bits/stdc++.h>
using namespace std;
char mp[1000][1000];
char s[1000][1000];
int main(){
    int T;
    scanf("%d",&T);
    while(T--){
        int n,m,k;
        scanf("%d%d%d",&n,&m,&k);
        for(int i=0;i<n;i++){   
            scanf("%s",s[i]);
        }
        for(int i=0;i<n;i++){
            for(int j=0;j<n;j++){
                mp[i][j]='.';
            }
        }
        int flag=0;
        int step;
        for(int i=0;i<k;i++){
            int a,b;
            scanf("%d%d",&a,&b);
            if(flag) continue;
            if(s[a-1][b-1]=='*'){
                flag=1;
                step=i+1;  
            }
            else{
                if(s[a-1][b-1]=='.') mp[a-1][b-1]='0';
                else mp[a-1][b-1]=s[a-1][b-1];
            }
                 
        }
        if(flag){
            printf("Game over in step %d\n",step);
        }
        else{
            for(int i=0;i<n;i++){
                for(int j=0;j<n;j++){
                    printf("%c",mp[i][j]);
                }
                printf("\n");
            }
        }
    }
}
/*
1
5 5 3
2*11*
*2111
22...
*1...
11...
1 1
3 3
1 2
*/

链接:https://www.nowcoder.com/acm/contest/118/G
来源:牛客网

火车上的2连座
时间限制:C/C++ 1秒,其他语言2秒
空间限制:C/C++ 32768K,其他语言65536K
64bit IO Format: %lld

题目描述


程序员A和B要去一起坐火车,这列火车上的每一排都有4个座位,而且这四个座位
被过道分成了两半。当A和B到了车上时,一些位子已经有人了。
A和B是好基友,于是他们想要找一对连在一起的座位。两个连在一起的座位是同一排但是不被过道隔开的两个座位。给定一列火车上的座位情况,请你寻找一下能否找到一对连座?

输入描述:

每组样例第一行为一个整数n,1<=n<=1000,表示火车一共有n排座位。
之后的n行每行为一个含有五个字符的字符串,第i个字符串的五个字符表示第i排座位的情况。每一个字符串的第三个字符都为字符‘|’,表示过道,其余每个字符表示一个座位的占用情况。字符'O'表示座位为空,字符'X'表示座位上已经有人,即被占用。

输出描述:

如果能够找到一组连座,则先输出一行字符串“YES”(不要输出引号)在第一行,在接下来的n
行输出车的座位情况,除了A和B的座位用字符'+'表示,其余输出格式与输入格式中车的座位情况一致。
如果不能够找到一组连座,仅输出一行“NO”(不要输出引号)即可。
有多组座位安排方式时,将A和B安排在前面的排,如果同一排还有两组可行解,选择将A和B排在左边。
例如一组车的情况为这样的时候,应该将其安排为箭头右边的情况。
OO|OO --> ++|OO
OO|OO --> OO|OO
示例1

输入

6
OO|OX
XO|XX
OX|OO
XX|OX
OO|OO
OO|XX
4
XO|OX
XO|XX
OX|OX
XX|OX
5
XX|XX
XX|XX
XO|OX
XO|OO
OX|XO

输出

YES
++|OX
XO|XX
OX|OO
XX|OX
OO|OO
OO|XX
NO
YES
XX|XX
XX|XX
XO|OX
XO|++
OX|XO

说明

注意
第一组样例中,下面的安排是不合法的。
O+|+X
XO|XX
OX|OO
XX|OX
OO|OO
OO|XX
思路:水;
代码:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
#include<bits/stdc++.h>
using namespace std;
char s[1005][8];
int main(){
    int n;
    while(~scanf("%d",&n)){
         for(int i=0;i<n;i++){
            scanf("%s",s[i]);
         }
         int i;
         for(i=0;i<n;i++){
            if(s[i][0]=='O'&&s[i][1]=='O'){
                s[i][0]=s[i][1]='+';
                break;
            }
            if(s[i][3]=='O'&&s[i][4]=='O'){
                s[i][3]=s[i][4]='+';
                break;
            }
         }
         if(i==n)
            printf("NO\n");
        else {
            printf("YES\n");
            for(int i=0;i<n;i++){
                printf("%s\n",s[i]);
            }
        }
    }
}

链接:https://www.nowcoder.com/acm/contest/118/H
来源:牛客网

程序员的好印象
时间限制:C/C++ 1秒,其他语言2秒
空间限制:C/C++ 32768K,其他语言65536K
64bit IO Format: %lld

题目描述


有一个程序员做过 n 个项目,他想要跳槽,因此他想要给面试官留下一个好印象。于是他想使自己看起来很有潜力也相应的会有竞争力,于是他决定从自己以前做过的N个成功或者失败的项目里不改变原来的时间顺序从中选择若干个项目,使得他展示出来的任意一个成功的项目之后都不会有一个失败的项目。这样一来,能够表现出他十足的潜力:尽管一开始做项目会失败,但一旦学会之后就不会再失败。具体的来说,给定一个含 n 个数字的“01”序列,如一个含5个数字的“01”序列:0 0 0 0 1,其中0代表失败的项目,1代表成功的项目。即第一个0代表第一个失败的项目,第二个0代表第二个失败的项目......最后一个1代表第五个成功的项目。于是如果这个程序员将选取一个原序列的一个子序列 0 0 0 0,满足上面他的要求:任意的数字1之后都没有数字0出现。程序员的目的是为了在满足上面的要求的条件下尽可能的展示最多的项目,请帮他算最多能展示多少个项目。

输入描述:

每组样例第一行为一个整数n,1<=n<=100,第二行为n项的01序列,每一项之间用一个空格隔开。

输出描述:

输出一个正整数,表示最多能展示的项目个数。
示例1

输入

4
1 1 0 1
6
0 1 0 0 1 0
1
0

输出

3
4
1
思路:dp; dp[i]=max(dp[j]+1,dp[i]); 这我一开始也没想到dp还是看了别人写的才懂的
代码:

#include<bits/stdc++.h>
using namespace std;
int n;
int a[105];
int dp[105];
int main(){
  while(~scanf("%d",&n)){
    for(int i=0;i<n;i++){
      scanf("%d",&a[i]);
      dp[i]=1;
    }
    for(int i=0;i<n;i++){
      for(int j=0;j<i;j++){
        if(a[i]>=a[j])
          dp[i]=max(dp[i],dp[j]+1);
      }
    }
    int ma=0;
    for(int i=0;i<n;i++){
      if(ma<dp[i]){
        ma=dp[i];
      }
    }
    printf("%d\n",ma);
  }
}

posted on 2018-05-06 12:50  大海浩瀚  阅读(1090)  评论(0)    收藏  举报

导航