蘑菇街2016研发工程师在线编程题

传送门

第一题:

[编程题] 搬圆桌
现在有一张半径为r的圆桌,其中心位于(x,y),现在他想把圆桌的中心移到(x1,y1)。每次移动一步,都必须在圆桌边缘固定一个点然后将圆桌绕这个点旋转。问最少需要移动几步。

输入描述:
一行五个整数r,x,y,x1,y1(1≤r≤100000,-100000≤x,y,x1,y1≤100000)


输出描述:
输出一个整数,表示答案

输入例子:
2 0 0 0 4

输出例子:
1

题解转自:
ixiaomo
 
思路很简单,千万别想复杂了
无论圆桌如何移动,都必须在圆桌边缘找一个点旋转。这就表明旋转后的圆心与最初的圆心连线肯定是2r的倍数(两圆心,向x轴或y轴做垂线,能得到一个直角三角形),几倍就表示最终移动了几步。
 
 
 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstdlib>
 4 #include<cmath>
 5  
 6 using namespace std;
 7  
 8 #define ll long long
 9  
10 double r,x[3],y[3],R;
11 int ans;
12  
13 void ini(){
14     int i;
15     for(i = 0;i <= 1;i++){
16         scanf("%lf%lf",&x[i],&y[i]);
17     }
18     R = 2 * r;
19     ans = 0;
20 }
21  
22 void solve(){
23     double dx,dy;
24     dx = x[0] - x[1];
25     dy = y[0] - y[1];
26     double d2, R2, d;
27     d2 = dx * dx + dy * dy;
28     d = sqrt(d2);
29     ans = (d + 0.5) / R;
30 }
31  
32 void out(){
33     printf("%d\n",ans);
34 }
35  
36 int main(){
37     while(scanf("%lf",&r) != EOF){
38         ini();
39         solve();
40         out();
41     }
42 }
View Code

 

这题涉及精度问题,下面这个人的解答不错(Zenas):

 1 //当初是在杭电acm的acmcoder网上考的,按照acm的“标准”,while循环输入。
 2 #include <iostream>
 3 #include <cmath>
 4 usingnamespace std ;
 5 
 6 int main(int argc, const char * argv[]) {
 7     // insert code here...
 8     int r, x, y, x1, y1;
 9     double length, lx, ly, s;
10     while (cin>>r>>x>>y>>x1>>y1) {
11         lx = (x1-x)>=0 ? (x1-x) : (x-x1);
12         ly = (y1-y)>=0 ? (y1-y) : (y-y1);
13         length = sqrt(lx*lx + ly*ly);
14         s = length/(2*r);
15         int t = (int)s;
16         if (s - t > 0)
17             cout << t+1 <<endl;
18         else
19             cout << t << endl;
20     }
21     return 0;
22 }
View Code

 

第二题:

 1 [编程题] 最大间隔
 2 给定一个递增序列,a1 <a2 <...<an 。定义这个序列的最大间隔为d=max{ai+1 - ai }(1≤i<n),现在要从a2 ,a3 ..an-1 中删除一个元素。问剩余序列的最大间隔最小是多少?
 3 
 4 输入描述:
 5 第一行,一个正整数n(1<=n<=100),序列长度;接下来n个小于1000的正整数,表示一个递增序列。
 6 
 7 
 8 输出描述:
 9 输出答案。
10 
11 输入例子:
12 5
13 1 2 3 7 8
14 
15 输出例子:
16 4
View Code

 

1、记录相邻节点之间间隔的最大值maxDis;
2、记录[i - 1]与[i + 1]结点之间的最小值minDis;
3、返回max(maxDis, minDis)
 
 
第五题:
[编程题] 回文串
给定一个字符串,问是否能通过添加一个字母将其变为回文串。

输入描述:
一行一个由小写字母构成的字符串,字符串长度小于等于10。


输出描述:
输出答案(YES\NO).

输入例子:
coco

输出例子:
YES


思路:
判断原字符串和翻转字符串的最长公共子序列长度是否比原字符串长度小1或相等
 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstdlib>
 4 #include<cstring>
 5 #include<cmath>
 6  
 7 using namespace std;
 8  
 9 #define N 15
10  
11 char s[N];
12 int le;
13 int flag;
14 int dp[N][N];
15  
16 void ini(){
17     le = strlen(s);
18     flag = 0;
19     memset(dp,-1,sizeof(dp));
20 }
21  
22 int dfs(int l,int r){
23     if(dp[l][r] != -1) return dp[l][r];
24     if(l > r){
25         return dp[l][r] = 0;
26     }
27     if(l == r){
28         return dp[l][r] = 1;
29     }
30     if(l + 1 == r){
31         if(s[l] == s[r]){
32             dp[l][r] = 2;
33         }
34         else{
35             dp[l][r] = 1;
36         }
37         return dp[l][r];
38     }
39     if(s[l] == s[r]){
40         dp[l][r] = dfs(l + 1,r - 1) + 2;
41     }
42     else{
43         dp[l][r] = max(dfs(l,r - 1),dfs(l + 1,r));
44     }
45     //printf(" l = %d r =%d dp =%d\n",l,r,dp[l][r]);
46     return dp[l][r];
47 }
48  
49 void solve(){
50     dfs(0,le - 1);
51 }
52  
53 void out(){
54     //printf(" %d\n",dp[0][le - 1]);
55  
56     if(dp[0][le - 1] == le - 1 || dp[0][le - 1] == le - 2){
57         printf("YES\n");
58     }
59     else{
60         printf("NO\n");
61     }
62 }
63  
64 int main(){
65     //freopen("in.txt","r",stdin);
66     while(scanf("%s",s) != EOF){
67         ini();
68         solve();
69         out();
70     }
71 }
View Code

 

posted on 2016-06-29 10:58  njczy2010  阅读(189)  评论(0编辑  收藏  举报