九度oj 王道论坛研究生机试练习赛第三场

来源:互联网 发布:淘宝sma是雪梨的店吗 编辑:程序博客网 时间:2024/04/28 11:09

昨晚做了九度oj上的练习赛。。

让我感觉这些题目对于acm来说真是心不难。。

好了,闲话少说,就给出最后两道的题解。

题目1551:切蛋糕

时间限制:1 秒

内存限制:128 兆

特殊判题:

提交:236

解决:71

题目描述:

有如下图半价为R的圆形蛋糕,被切一刀后(图中红色直线),分成两个部分(黄色和绿色),已知其比例为r,求刀痕长度(图中红色直线)。

输入:

输入包括多组测试数据,包括一个整数R(1<=R<=1000),和一个浮点数r(0<r<1),精确到第四位小数。

输出:

对于每组测试用例,输出一个浮点数,代表刀痕的长度,保留二位小数。

样例输入:
1000 0.5000500 0.6183
样例输出:
1928.53982.49
来源:
2014年王道论坛研究生机试练习赛(三)
这道是我见过的最纯粹的几何题。

首先是要靠你一步一步推出公式

假设半径为R,比例为f

S为圆的面积

q为切线交点和圆心的连线的角度的一半

然后可知切割后的一部分面积为x = (f*S)/(f+1)

然后R^2*q - R^2*sin(2*q)/2 = x

对于这条方程最主要就是求出q的值,但是~~我不会

所以我就用最简单的方法求:二分求值

然后ans = 2.0*R*sin(mid)

#include<cstdio>#include<cstring>#include<algorithm>#include<queue>#include<vector>#include<math.h>using namespace std;#define pi 3.1415926int main(){    int n,i,j;    int sum;    double R,f;while(~scanf("%lf%lf",&R,&f)){double S = R*R*pi;if(f>1.0)f = 1.0/f;double var = (f*S)/(f+1.0)/(R*R) ;double l = 0,r = pi/2.0,mid;while(1){mid = (l+r)/2.0;if(mid-sin(2.0*mid)*0.5>var)r = mid;elsel = mid;if(r-l<0.00000001)break;}printf("%0.2f\n",2.0*R*sin(mid));}    return 0;}

————————————————————————————————————————————————————————————

————————————————————————————————————————————————————————————

题目1552:座位问题

时间限制:1 秒

内存限制:128 兆

特殊判题:

提交:227

解决:60

题目描述:

计算机学院的男生和女生共n个人要坐成一排玩游戏,因为计算机的女生都非常害羞,男生又很主动,所以活动的组织者要求在任何时候,一个女生的左边或者右边至少有一个女生,即每个女生均不会只与男生相邻。现在活动的组织者想知道,共有多少种可选的座位方案。


例如当n为4时,共有
女女女女, 女女女男, 男女女女, 女女男男, 男女女男, 男男女女, 男男男男
7种。

输入:

输入包含多组测试用例,每组测试用例仅包含一个整数n(1<=n<=1000)。

输出:

对于每组测试用例,输出一个数代表可选的方案数,为防止答案过大,答案对1000000007取模。

样例输入:
124
样例输出:
127
来源:
2014年王道论坛研究生机试练习赛(三)
最后一题,一看到这种题目就应该想到动态规划

不过哥状态方程我也想了很久,丢脸!~~~

dp[i][j]表示第i个放男和女的个数(j为0是男,j为1是女)

然后很容易dp[i][0] = dp[i-1][0]+dp[i-1][1];

关键就是dp[i][1]这么表示

其实dp[i][1] = sum(dp[k][0])(k = 0~i-2)

其实意思就是最后一个放女的那倒数第二个就一定也是女的但是男的最后一个放在那里呢

就是枚举最后一个男的位置

把所有的情况都考虑了一遍

这个操作可以用单调队列来实现

最后时间复杂度就变成里O(n)

#include<cstdio>#include<cstring>#include<algorithm>#include<queue>#include<vector>#include<math.h> using namespace std;#define MOD 1000000007int dp[1005][3];void Init(){    int i,j;    memset(dp,0,sizeof(dp));    dp[1][0] = 1;    dp[1][1] = 0;    dp[0][0] = 1;    //dp[2][]    int sum = 0;    for(i=2;i<1003;i++)    {        dp[i][0] = (dp[i-1][0]+dp[i-1][1])%MOD;        sum = (sum+dp[i-2][0])%MOD;        dp[i][1]=(dp[i][1]+sum)%MOD;            }     }int main(){    int n,i,j;    Init();    while(~scanf("%d",&n))    {           printf("%d\n",(dp[n][0]+dp[n][1])%MOD);    }    return 0;     }


5 1
原创粉丝点击