This page looks best with JavaScript enabled

2020浙江理工大学算法艺术与信息学奥赛选修课期末考试

 ·  ☕ 5 min read · 👀... views

总结:学过算法的可以水学分 没学过的不太好水高分 一般c语言学了70-80分没问题 但是90-100有难度 自行斟酌

问题 A: 赌徒

题目描述

有n个赌徒打算赌一局。规则是:
每人下一个赌注,赌注为非负整数,且任意两个赌注都不相同。胜者为赌注恰好是其余任意三个人的赌注之和的那个人。如果有多个胜者,我们取赌注最大的那个为最终胜者。
例如,A,B,C,D,E分别下赌注为2、3、5、7、12,最终胜者是E,因为12=2+3+7。

输入

输入包含多组测试数据。每组首先输入一个整数n(1<=n<=1000),表示赌徒的个数。
接下来n行每行输入一个非负整数b(0<=b<32768),表示每个赌徒下的赌注。
当n=0时,输入结束。

输出

对于每组输入,输出最终胜者的赌注,如果没有胜者,则输出no solution。

简单思路

直接暴力 但是我总觉得数据稍微大点这题绝对不能这么做

 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
#include<iostream>
#include<cstdio>
#include<cmath>
#include<queue>
#include<cstring>
#include<algorithm>
using namespace std;
bool cmp(int a,int b){
    return a>b;
}
int main(){
    int n;
    int a[1111];
    while(cin>>n && n){
        for(int i=1;i<=n;i++)
            cin>>a[i];
        sort(a+1,a+1+n,cmp);
        int flag=0;
        for(int t=1;t<=n;t++){
            for(int i=t+1;i<=n;i++){
                for(int j=i+1;j<=n;j++){
                    for(int k=j+1;k<=n;k++){
                        if(a[i]+a[j]+a[k]==a[t]){
                            cout<<a[t]<<endl;
                            flag=1;
                            break;
                        }
                    }
                    if(flag) break;
                }
                if(flag) break;
            }
            if(flag) break;
        }
        if(!flag)
            cout<<"no solution\n";
    }
    return 0;
}

问题 B: ASCII码

题目描述

相信大家一定都知道大名鼎鼎的ASCII码,这次给你的任务是输入数字(表示ASCII码),输出相对应的字符信息。

输入

第一行为一个整数T(1<=T<=1000)。
接下来包括T个正整数,由空白符分割。(空白符包括空格、换行、制表符)
这些整数不会小于32。

输出

在一行内输出相应的字符信息。(注意不要输出任何多余的字符)

简单思路

直接强转就行了

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
#include<iostream>
#include<cstdio>
#include<cmath>
#include<queue>
#include<cstring>
#include<algorithm>
using namespace std;
int main(){
    int t;
    while(cin>>t){
        while(t--){
            int a;
            cin>>a;
            cout<<(char)a;
        }
        cout<<endl;
    }
    system("pause");
    return 0;
}

问题 C: 期末成绩

题目描述

又到学期末,小明迎来了又一次的期末考试。虽然每学期都要考试,但是这次期末考试对小明来说意义重大。因为小明爱慕已久的女神说,如果小明这次考了全班前三名就做他女朋友。虽说小明没有十足的信心,但是女神的话不能不听啊。
考完试后,小明拿到了全班的成绩单,这张成绩单是按学号顺序排好的。小明很想知道班里到底有多少人分数比他高,现在就请你帮帮他,帮他数一下到底有多少人的分数比他高吧。

输入

输入数据的第一行是一个正整数T,表示测试数据的组数,接下来有T组测试数据。
每组数据包括两行。
第一行有两个正整数N,K(0<N<1000,0<K<=N),分别表示成绩单上总共的学生数目,和小明的学号。
第二行有N个整数Xi(0<=Xi<=100)分别表示各个学生的成绩,以学号递增顺序给出,第一个学生学号为1。

输出

对于每组数据,请在一行里输出班里一共有多少个学生成绩高于小明。

样例输入

1
3 2
81 72 63

样例输出

1

简单思路

for历遍一下就可以

 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
#include<iostream>
#include<cstdio>
#include<cmath>
#include<queue>
#include<cstring>
#include<algorithm>
using namespace std;
int main(){
    int t;
    int n,k;
    while(cin>>t){
        while(t--){
            int a[2000]={0};
            memset(a,0,sizeof(a));
            cin>>n>>k;
            for(int i=1;i<=n;i++)
                cin>>a[i];
            int t=a[k];
            int count=0;
            for(int i=1;i<=n;i++)
                if(a[i]>t)
                    count++;
            cout<<count<<endl;
        }
    }
    return 0;
}

问题 D: 【基础题】尽可能大的三位数

题目描述

输入一个三位数的正整数,将数字位置重新排列,组成一个尽可大的三位数。例如:输入213,重新排列可得到尽可能大的三位数是321。

输入

三位数的正整数。

输出

重排后尽可能大的三位数。

样例输入

213

样例输出

321

简单思路

sort一下就行

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
#include<iostream>
#include<cstdio>
#include<cmath>
#include<queue>
#include<cstring>
#include<algorithm>
#include<set>
using namespace std;
bool cmp(char a,char b){
    return a>b;
}
int main(){
    char a[10];
    while(cin>>a[0]>>a[1]>>a[2]){
        sort(a,a+3,cmp);
        cout<<a[0]<<a[1]<<a[2]<<endl;
    }
    return 0;
}

问题 E: 会场安排问题

题目描述

假设要在足够多的会场里安排一批活动,并希望使用尽可能少的会场。设计一个有效的
贪心算法进行安排。(这个问题实际上是著名的图着色问题。若将每一个活动作为图的一个
顶点,不相容活动间用边相连。使相邻顶点着有不同颜色的最小着色数,相应于要找的最小
会场数。)

编程任务:

对于给定的 k 个待安排的活动,编程计算使用最少会场的时间表。

输入

第一行有 1 个正整数 k,表示有 k 个待安排的活动。接
下来的 k 行中,每行有 2 个正整数,分别表示 k 个待安排的活动开始时间和结束时间。时间
以 0 点开始的分钟计。

输出

将编程计算出的最少会场数输出

样例输入

5
1 23
12 28
25 35
27 80
36 50

样例输出

3

提示

k<10000

简单思路

begin排序 end小了就开一个会场

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#include<iostream>
#include<cstdio>
#include<cmath>
#include<queue>
#include<cstring>
#include<algorithm>
using namespace std;
int s[11111],e[11111];
int main(){
    int n=0,i=0,j=0,k=0;
    cin>>n;
    for(;i<n;i++)
        cin>>s[i]>>e[i];
    sort(s,s+n);
    sort(e,e+n);
    for(i=0;i<n;i++) {
        if(s[i]<e[j]) k++;
        else j++;
    }
    cout<<k<<endl;
    system("pause");
    return 0;
}

问题 F: 飞翔

题目描述

鹰最骄傲的就是翱翔,但是鹰们互相都很嫉妒别的鹰比自己飞的快,更嫉妒其他的鹰比自己飞行的有技巧。于是,他们决定举办一场比赛,比赛的地方将在一个迷宫之中。
这些鹰的起始点被设在一个N*M矩阵的左下角map[1,1]的左下角。终点被设定在矩阵的右上角map[N,M]的右上角,有些map[i,j]是可以从中间穿越的。每一个方格的边长都是100米。如图所示:

没有障碍,也没有死路。这样设计主要是为了高速飞行的鹰们不要发现死路来不及调整而发生意外。潘帕斯雄鹰冒着减RP的危险从比赛承办方戒备森严的基地中偷 来了施工的地图。但是问题也随之而来,他必须在比赛开始之前把地图的每一条路都搞清楚,从中找到一条到达终点最近的路。(哈哈,笨鸟不先飞也要拿冠军)但 是此鹰是前无古鹰,后无来鹰的吃菜长大的鹰–菜鸟。他自己没有办法得出最短的路径,于是紧急之下找到了学OI的你,希望找到你的帮助。

输入

首行为n,m(0<n,m<=1000000),第2行为k(0<k<=1000)表示有多少个特殊的边。以下k行为两个数,i,j表示map[i,j]是可以直接穿越的。

输出

仅一行,1,1–>n,m的最短路径的长度,四舍五入保留到整数即可

样例输入

3 2
3
1 1
3 2
1 2

样例输出

383

简单思路

找最长上升的数量 即走斜线的数量
然后就是找上升个数和长度的规律(其实一目了然) 4舍5入

 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
//n,m小的话可以dfs 但是这个太大了。。。 
//其实算出上升数量就行了
#include<iostream>
#include<cstdio>
#include<cmath>
#include<queue>
#include<cstring>
#include<algorithm>
using namespace std;
struct N{
    int x;
    int y;
};
N node[1111];
int dp[1111];
bool cmp(N a, N b){
    return a.x<b.x;
}
int main(){
    int n,m,k;
    while(cin>>n>>m>>k){
        memset(dp,0,sizeof(dp));
        for(int i=0;i<k;i++)
            cin>>node[i].x>>node[i].y;
        sort(node,node+k,cmp);
        int maxn = 0;
		for(int i=0;i<k;i++){
			dp[i]=1;
			for(int j=0;j<i;j++)
				if(node[i].x > node[j].x && node[i].y > node[j].y && dp[i] < dp[j]+1)
					dp[i] = dp[j]+1;
			if(dp[i] > maxn)
				maxn = dp[i];
        }
        double t=100.0*(n+m-2*maxn)+sqrt(2)*100.0*maxn;
        cout<<(int)(t+0.5)<<endl;
    }
    return 0;
}
Share on

ruokeqx
WRITTEN BY
ruokeqx