2021-11-04算法期中考

A 院庆抽奖(分治法)1000MS64MB

Description

为了庆祝信息学院成立20周年,学院举行了网络抽奖活动,每个信息学院的校友和教师都分配一个不重复号码,随机进行抽奖。请你设计一个高效的算法,根据获奖号码找到获奖者的姓名。如果该号码不存在,则输出none。请用分治法实现,禁止调用库函数,否则没有分数。要求算法的最坏时间复杂度为O(logn)

Input

第一行一个数字n,表示共有多少人参与抽奖, 1<=n<10^6 下面n行,每行包含号码和姓名,以空格分隔,已按号码升序进行了排序 下面一行,获奖号码,以空格分隔,表示获奖者的编号,号码为0时表示结束

Output

输出获奖者的姓名,姓名以空格分隔

Sample Input 1Copy

5

1 乔布斯

3 扎克伯格

8 李开复

9 雷军

11 马化腾

11 3 7 0

Sample Output 1

马化腾 扎克伯格 none

Hint

提示

#include<iostream>
using namespace std;
int a[1000000];
string name[1000000];
string Bi(int a[1000000], int key, int n)
{
	int left = 0;
	int right = n - 1;
	while (left <= right)
	{
		int middle = (left + right) / 2;
		if (a[middle] == key)
		{
			
			return name[middle];
		}

		if (a[middle] < key)
		{
			left = middle + 1;
		}
		else
		{
			right = middle - 1;
		}
	}
	
	return "none";
}
int main()
{
	int n;
	cin >> n;
	for (int i = 0;i < n;i++)
	{
		cin >> a[i];
		cin >> name[i];
	}
	int q;
	cin >> q;
	while (q > 0)
	{
		cout << Bi(a, q, n) << " ";//不要在Binary()函数里面输出,要在函数外,不然会出现差错




		cin >> q;

	}





}

B 程序设计竞赛之路(分治)1000MS64MB

Description

院庆时总是让人禁不住回忆学院从无到有的点点滴滴。学院组队参加第一次大学生程序设计比赛区域赛是2008年的合肥站,初次参赛经验不足,没有任何收获。后面经过若干次大赛的洗礼,终于在2013年长沙站首次获得了铜牌,2014年广州站首次获得了银牌,2020年南京站首次获得了金牌。这些成绩的取得都离不开队员刻苦的训练。如果你热爱编程,希望你也能刻苦学习,继续创造学院的辉煌。学院从2008年开始每年都会参加几场大学生程序设计比赛区域赛,请你帮忙找出如果按照时间排序,参加的第k场比赛是在哪一天。注意:直接用排序算法不得分,可以参考快速排序的思路,要求算法的平均时间复杂度为O(n)

Input

第一行一个数字n,表示共有多少场比赛 第二行n个数字以空格分隔,表示每场比赛的比赛的日期,日期格式为YYYYMMDD 下面一行一个数字k,表示查询的是第k场比赛的时间。

Output

第k场比赛的时间

Sample Input 1

5

20081117

20180901

20101203

20101111

20191105

3

Sample Output 1

20101203

Hint

提示

#include<iostream>

using namespace std;

int a[10000];

void swap(int& c, int& d)

{

    int temp;

    temp = c;

    c = d;

    d = temp;

}

int sort(int a[10000], int l, int r)

{

    int i = l;

    int j = r + 1;

    int x = a[l];

    while (true)

    {

         while (a[++i] < x && i < r);

         while (a[--j] > x);

         if (i >= j)

         {

             break;

         }

         swap(a[i], a[j]);

    }

    a[l] = a[j];

    a[j] = x;

    return j;

}

void kuai(int a[10000], int l, int r)

{

    if (l < r)

    {

         int q = sort(a, l, r);

         kuai(a, l, q - 1);

         kuai(a, q + 1, r);

    }

}

int main()

{

    int n;

    cin >> n;

    for (int i = 0;i < n;i++)

    {

         cin >> a[i];

    }

    kuai(a, 0, n - 1);

    int e;

    cin >> e;

    cout << a[e - 1];

}

C 回忆之路(动态规划)1000MS64MB

Description

学院举办院庆时会邀请校友返校。校友返校后,经常会漫步校园,参观教学楼、实验室、图书馆,回忆他曾经学习和生活的点点滴滴。学校的形状为三角形高为n,景点的坐标表示为(i,j),每个景点都有一个回忆值。校友从曾经居住的13栋,坐标为(0, 0),出发,一直走到体育馆,坐标为(n-1, n-1)。由于时间比较紧张,所以只能向下走,或者向右走。请你帮忙计算参观路线的最大回忆值。要求算法的时间复杂度为O(n^2)

Input

第一行一个数字n,表示三角形的行数。2<=n<100 第二行一个数字m,表示景点数 接下来m行,每行3个数字,以空格分隔,表示景点的坐标(i, j)和回忆值v,0<=i<=n-1, 0<=j<=n-1, 1<=v<=100

Output

参观路线的最大回忆值

Sample Input 1Copy

5

6

0 0 6

1 1 3

2 0 2

3 0 2

3 2 7

4 4 8

Sample Output 1

25

Hint

校园地图为

6

* 3

2 * *

2 * 7

* * * 8 最优路线为6->2->2->7->8,回忆值为25

#include<iostream>

#include<algorithm>

using namespace std;

int a[100][100] = { 0 };

int main()

{

       int n;

       cin >> n;

       if (n >= 2 && n < 100)

       {

              int m;

              cin >> m;

              int i, j, value;

              for (int x = 0;x < m;x++)

              {

                     cin >> i >> j >> value;

                     a[i + 1][j + 1] = value;

              }

              for (int x = 1;x <= n;x++)

              {

                     for (int y = 1;y <= n;y++)

                     {

                            a[x][y] = max(a[x - 1][y], a[x][y - 1]) + a[x][y];

                     }

              }

              cout << a[n][n];

       }

       else

              return 0;

}

D 校友调查(动态规划)1000MS64MB

Description

校友返校后,算法老师想知道是不是在校时算法学得越好,毕业后的薪酬越高。于是算法老师找出了校友们在校时算法的成绩单,并且询问了每位校友的薪酬。算法老师希望找出最长校友的序列,满足算法成绩是严格递增的,同时薪酬也是严格递增的。要求算法的时间复杂度为O(nlogn)

Input

第一行一个数字n,表示调查的校友总数, 1<=n<=100 下面n行,每行2个正整数用空格分隔,表示校友的算法成绩grade和薪酬salary, 0<=grade<=100, 0

Output

满足递增条件的校友序列最长的长度

Sample Input 1Copy

5

76 300000

82 500000

93 900000

89 200000

65 100000

Sample Output 1

4

Hint

校友序列为(65,100000)、(76,300000)、(82,500000)、(93,900000)

#include<iostream>

#include<algorithm>

using namespace std;

int a[1000] = { 10000000 };

int b[1001] = { 0 };

int main()

{

       int Count = 0;

       int n;

       cin >> n;

       int grade, salary;

       for (int i = 0;i < n;i++)

       {

              cin >> grade>>salary;

              a[grade] = salary;

       }

      

       for (int i = 0;i <= 100;i++)

       {

              for (int j = 0;j <=i;j++)

              {

                     if (a[i] > a[j] )

                     {

                            b[i] =max( b[j] + 1,b[i]);//用这种方法最后一定要排序选出最大的b[i],b[i]的意思是以a[i]为末尾(这个序列里要包含a[i])的最长单调子序列,所以如1 3 5 9 2的以2为末尾的最长单调子序列就为2(1、2);

                     }

              }

       }

       sort(b , b + 100);

       cout << b[99];

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值