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];
}