牛客网--蘑菇街2016研发工程师编程题
第一题: 搬圆桌
时间限制:1秒
空间限制:32768K
现在有一张半径为r的圆桌,其中心位于(x,y),现在他想把圆桌的中心移到(x1,y1)。每次移动一步,都必须在圆桌边缘固定一个点然后将圆桌绕这个点旋转。问最少需要移动几步。
输入描述:
一行五个整数r,x,y,x1,y1(1≤r≤100000,-100000≤x,y,x1,y1≤100000)
输出描述:
输出一个整数,表示答案
输入例子1:
2 0 0 0 4
输出例子1:
1
#include <cstdio> #include <cmath> int main(){ int r, x1, x2, y1, y2; while(scanf("%d", &r) != EOF){ scanf("%d %d", &x1, &y1); scanf("%d %d", &x2, &y2); double len = sqrt(1.0*(x2 - x1)*(x2 - x1) + 1.0*(y2 - y1)*(y2 - y1)); int int_len = (int)(len); int ans = int_len / (2*r); if(fabs(ans*2*r - len) >= 1e-8){ ++ans; } printf("%d ", ans ); } return 0; }
第二题] 最大间隔
时间限制:1秒
空间限制:32768K
给定一个递增序列,a1 <a2 <...<an 。定义这个序列的最大间隔为d=max{ai+1 - ai }(1≤i<n),现在要从a2 ,a3 ..an-1 中删除一个元素。问剩余序列的最大间隔最小是多少?
输入描述:
第一行,一个正整数n(1<=n<=100),序列长度;接下来n个小于1000的正整数,表示一个递增序列。
输出描述:
输出答案。
输入例子1:
5
1 2 3 7 8
输出例子1:
4
#include <cstdio> #include <cstring> const int MAXN = 1005; int n, num[MAXN]; int main(){ while(scanf("%d", &n) != EOF){ for(int i=0; i<n; ++i){ scanf("%d", &num[i]); } int max_gap = num[1] - num[0]; for(int i=1; i<n; ++i){ if(max_gap < num[i] - num[i-1]){ max_gap = num[i] - num[i-1]; } } int ans = 0x3f3f3f3f; for(int i=2; i<n; ++i){ if( ans > num[i] - num[i-2] ){ ans = num[i] - num[i-2]; } } if(ans < max_gap){ ans = max_gap; } printf("%d ", ans ); } return 0; }
第三题 [编程题] 聊天
时间限制:1秒
空间限制:32768K
A和B是好友,他们经常在空闲时间聊天,A的空闲时间为[a1 ,b1 ],[a2 ,b2 ]..[ap ,bp ]。B的空闲时间是[c1 +t,d1 +t]..[cq +t,dq +t],这里t为B的起床时间。这些时间包括了边界点。B的起床时间为[l,r]的一个时刻。若一个起床时间能使两人在任一时刻聊天,那么这个时间就是合适的,问有多少个合适的起床时间?
输入描述:
第一行数据四个整数:p,q,l,r(1≤p,q≤50,0≤l≤r≤1000)。接下来p行数据每一行有一对整数ai,bi(0≤ai<bi≤1000)表示a的时间表,接下来p行每行一对整数ci,di(0≤ci,di≤1000)表示b的时间表。保证ai+1>bi,ci+1>di
输出描述:
输出答案个数
输入例子1:
2 3 0 20
15 17
23 26
1 4
7 11
15 17
输出例子1:
20
#include <cstdio> #include <cstdlib> #include <cstring> const int MAXN = 305; struct Time{ int s, e; }; int p, q, l, r; Time A[MAXN], B[MAXN]; int cmp(const void *a, const void *b){ Time *aa = (Time *)a; Time *bb = (Time *)b; if( aa->s == bb->s ){ return aa->e - bb->e; } return aa->s - bb->s; } bool Judge(int t){ int i = 0, j = 0; while(i < p && j < q){ if( (A[i].s<=B[j].s+t && A[i].e>=B[j].s + t) || ( A[i].s <= B[j].e+t && A[i].e >= B[j].s + t) ){ return true; }else if(A[i].e > B[j].s + t){ ++j; }else{ ++i; } } return false; } int main(){ while(scanf("%d %d %d %d", &p, &q, &l, &r) != EOF){ for(int i=0; i<p; ++i){ scanf("%d %d", &A[i].s, &A[i].e); } qsort(A, p, sizeof(A[0]), cmp); for(int i=0; i<q; ++i){ scanf("%d %d", &B[i].s, &B[i].e); } qsort(B, q, sizeof(B[0]), cmp); int ans = 0; for(int i=l; i<=r; ++i){ if(Judge(i)){ ++ans; } } printf("%d ", ans ); } return 0; }
第四题,[编程题] 投篮游戏
时间限制:1秒
空间限制:32768K
有一个投篮游戏。球场有p个篮筐,编号为0,1...,p-1。每个篮筐下有个袋子,每个袋子最多装一个篮球。有n个篮球,每个球编号xi 。规则是将数字为xi 的篮球投到xi 除p的余数为编号的袋里。若袋里已有篮球则球弹出游戏结束输出i,否则重复至所有球都投完。输出-1。问游戏最终的输出是什么?
输入描述:
第一行两个整数p,n(2≤p,n≤300)。p为篮筐数,n为篮球数。接着n行为篮球上的数字xi(0≤xi≤1e9)
输出描述:
输出游戏的结果
输入例子1:
10 5
0
21
53
41
53
输出例子1:
4
#include <cstdio> #include <cstring> const int MAXN = 305; int num[MAXN], vis[MAXN]; int main(){ int p, n, ans, flag; while(scanf("%d %d", &p, &n) != EOF){ memset(vis, 0, sizeof(vis)); ans = -1; flag = 1; for(int i=0; i<n; ++i){ scanf("%d", &num[i]); if(flag && vis[ num[i]%p ] == 0){ vis[ num[i]%p ] = 1; }else if(flag){ ans = i + 1; flag = 0; } } printf("%d ", ans ); } return 0; }
第五题,编程题] 回文串
时间限制:1秒
空间限制:32768K
给定一个字符串,问是否能通过添加一个字母将其变为回文串。
输入描述:
一行一个由小写字母构成的字符串,字符串长度小于等于10。
输出描述:
输出答案(YESNO).
输入例子1:
coco
输出例子1:
YES
#include <cstdio> #include <cstring> const int MAXN = 100; int main(){ char ch[MAXN]; while(scanf("%s", ch) != EOF){ getchar(); int ans = 1, len = strlen(ch); int l = 0, r = len - 1; if(ch[l] == ch[r]){ int flag = 1; while(l < r){ if(ch[l] == ch[r]){ ++l; --r; }else if(flag){ if(ch[l] == ch[r-1]){ --r; }else{ ++l; } flag = 0; }else{ ans = 0; break; } } }else{ if(ch[l] == ch[r-1]){ --r; }else{ ++l; } while(l < r){ if(ch[l] != ch[r]){ ans = 0; break; } ++l; --r; } } if(ans){ printf("YES "); }else{ printf("NO "); } } return 0; }