CodingTrip - 携程编程大赛 (预赛第一场)
2014-04-11 19:54
417 查看
聪明的猴子
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 1123 Accepted Submission(s): 294
Problem Description
森林中有一排香蕉树(无限长),一只猴子站在其中一棵树上,猴子在跳跃前要先抽取一张卡片,卡片上写有A+1个自然数,其中最后一个是B,前A个数只能小于等于B,卡片上的数字可以相同。猴子每次跳跃先从卡片上任选一个自然数C,然后向左、或向右跳C棵树。猴子的任务是:跳到与它左边相邻的香蕉树上时,就可以吃掉上面的香蕉。
例如,当A=2,B=4时,对于卡片(2, 3, 4),猴子就可以吃到香蕉:它可以先向左跳3棵树,再向右跳两棵树。而对于卡片(2, 2, 4),猴子则怎么也不可能跳到它左边相邻的香蕉树上。
当确定A和B后,则一共可以有B^A张不同的卡片。问题是,在这所有的卡片中,有多少张可以让猴子完成任务。
Input
第1行k,表示有k组测试数据,k<=100
第2至k+1行,每行两个自然数A和B,以一个空格分开 (A<= 10 , B <= 20)。
Output
共k行,每行的数字代表每组数据中,可以让猴子跳到它左边相邻香蕉树的卡片数。
Sample Input
3
2 3
4 8
5 13
Sample Output
8
3840
371292
给你两个正整数n,m,让你求长度为n+1的满足条件的一个等式:a[1]*x1+a[2]*x2+a[3]*x3+...+a
*xn+a[n+1]*x(n+1)=1 (0<=a[i]<=m&&a[n+1]=m)
让你求一共有多少种情况满足这个条件。
要使得a[1]*x1+a[2]*x2+a[3]*x3+...+a
*xn+a[n+1]*m=1 (0<=a[i]<=m),那么a[1],a[2],a[3]....a[n+1]的最大公约数为1.
要解决此题,你需要知道的知识有扩展欧几里得,鸽巢原理,以及递归求所有的排列组合。
例如:n=2,m=360
360=3^2*2^3*5 所有不满足条件的数列,最大公约数是360质因子的乘积,只要将这些组合去掉,就是要求的答案(不懂的慢慢揣摩)
那么就要先求出m的所有质因子,然后求出总的排列组合的个数,即题目中说的M^N,最后根据鸽巢原理求得最后答案。
公式为:ans=M^N-(有奇数个公因数的n元组)+(有偶数个公因数的n元组)。拿上面的例子来说就是
ans=m^n-(有公因数2的n元组)- (有公因数3的n元组)- (有公因数5的n元组)+ (有公因数2,3的n元组) +(有公因数2,5的n元组)+ (有公因数3,5的n元组)- (有公因数2,3,5的n元组).
有公因数d的n元组,每个位置上有 (m/d)个选择(1 ~ m里面有m/d个d的倍数),根据乘法原理,可以得出有公因数d的n元组有 (m/d)^n 个.
//400K 0MS #include<stdio.h> #define M 130007 long long num[M],s[M]; long long n,m,total,per; void sum_factor()//分解质因子,存在num里面 { total=0; long long t=m; for(int i=2;i*i<=t;i++) { if(t%i==0)num[total++]=i; while(t%i==0)t/=i; } if(t!=1)num[total++]=t; } long long pow(long long x,long long y)//求x^y { long long k=x; for(long long i=1;i<y;i++) x*=k; return x; } void dfs(long long a,long long b,long long c)//a在数组中的起始位置,b含的个数,c公共质因子的个数 { if(b==c) { long long t=m; //printf("("); for(long long i=0;i<c;i++) { //printf("%d ",s[i]); t/=s[i];//t表示每位上有几个包含质因子的数 } //printf(")\n"); per+=pow(t,n);//总共有多少个 } else { for(long long i=a;i<total;i++)//递归回溯求解所有排列组合 { s=num[i]; dfs(i+1,b+1,c); } } } int main() { int k; scanf("%d",&k); while(k--) { scanf("%I64d%I64d",&n,&m); sum_factor(); long long ans=pow(m,n); for(long long i=1;i<=total;i++) { per=0; dfs(0,0,i); if(i%2)ans-=per;//如果有奇数个公因数的n元组就相减 else ans+=per;//如果有奇数个公因数的n元组就相加 } printf("%I64d\n",ans); } return 0; }
携程全球数据中心建设
[b]Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 725 Accepted Submission(s): 307
Problem Description
携程为了扩展全球在线旅游业务,决定在全球建设多数据中心,以便提高网站的访问速度和容灾处理。
为了实现每个数据中心的数据能互通,数据中心之间需要通过光纤连接。为了节约光纤成本,我们计划采用点对点方式来达到最终各个数据中心的数据互通,每个数据中心本身都可以作为数据中转站。做为全球多数据中心设计者,您需要知道最短的光纤总长度,来把所有的数据中心都实现互通。假设地球是个圆球,且表面是平滑的,并且没有任何阻碍物(河流,山脉)。
输入数据是一组数据中心的经纬度
纬度: -90° 到 +90°
经度: -180° 到 +180°
(圆周率pi= 3.14159265358979323846)
Input
第一行第一个整数N(1≤N≤100),表示有多少个用例. 每个用例包含了:
第一行,小数D(1≤D≤1,000,000),表面圆球的直径(公里).
第二行,小数L(1≤L≤1,000,000) 光纤总长度 (公里).
第三行,整数C(1≤C≤100) ,表示数据中心的数量.
接下来的C行, 每行有2个形如"X Y"的小数,表示每个数据中心的纬度(-90≤X≤90)和经度 (-180≤Y≤180).
Output
每个用例输出一行. 如果光纤长度L足够连接所有数据中心,输出"Y", 否则输出"N"。
Sample Input
2
12742
5900
3
51.3 0
42.5 -75
48.8 3
12742
620
2
30.266 97.75
30.45 91.1333
Sample Output
Y
N
如何通过地球上两点上的经维度求他们的距离公式?
设球的半径为R,并且假设东经为正,西经为负,北纬为正,南纬为负。
则A(x,y)坐标可表示为(R*cosy*cosx, R*cosy*sinx, R*siny)
B(a,b)坐标可表示为(R*cosb*cosa, R*cosb*sina, R*sinb)
AB两点的的球面距离为:R*(arccos(cosb*cosy*cos(a-x)+sinb*siny))
最后直接最小生成树即可。
#include<stdio.h> #include<string.h> #include<math.h> #define MAX 99999999 const double pi=3.14159265358979323846; double g[110][110],lgtd[110],lttd[110]; int c; void init() { for(int i=1;i<107;i++) for(int j=1;j<107;j++) g[i][j]=MAX; } double prime() { double low[110]; int flag[110]; memset(flag,0,sizeof(flag)); for(int i=1; i<=c; i++) { low[i]=g[1][i]; } double count=0; flag[1]=1; for(int i=1; i<c; i++) { double min=MAX+1; int k; for(int j=1; j<=c; j++) { if(flag[j]==0&&min>low[j]) { min=low[j]; k=j; } } flag[k]=1; count+=low[k]; for(int j=1; j<=c; j++) { if(flag[j]==0&&low[j]>g[j][k]) { low[j]=g[j][k]; } } } return count; } int main() { int t; double d,l,lgtd[110],lttd[110]; scanf("%d",&t); while(t--) { scanf("%lf%lf%d",&d,&l,&c); for(int i=1;i<=c;i++) { scanf("%lf%lf",<td[i],&lgtd[i]); //弧度=角度*π/180 lgtd[i]=lgtd[i]*pi/180; lttd[i]=lttd[i]*pi/180; } d/=2; for(int i=1;i<=c;i++) for(int j=1;j<=c;j++) { if(i!=j) g[i][j]=d*acos(cos(lttd[j])*cos(lttd[i])*cos(lgtd[i]-lgtd[j])+sin(lttd[i])*sin(lttd[j])); } double ans=prime(); if(ans>l)printf("N\n"); else printf("Y\n"); } return 0; }
相关文章推荐
- CodingTrip - 携程编程大赛 (预赛第一场)
- CodingTrip - 携程编程大赛 (预赛第一场) 括号匹配
- CodingTrip - 携程编程大赛 (预赛第一场)
- CodingTrip - 携程编程大赛 (预赛第一场)旋转的二进制
- CodingTrip - 携程编程大赛 (预赛第二场) 位图像素的颜色
- CodingTrip - 携程编程大赛 (预赛第一场)第四题
- 2014 CodingTrip - 携程编程大赛 (预赛第一场)
- CodingTrip - 携程编程大赛 (预赛第一场)第三题 携程全球数据中心建设
- 携程编程大赛 (预赛第一场)1004旋转的二进制
- CodingTrip - 携程编程大赛 (预赛第二场):位图像素的颜色
- 【解题报告】[动态规划] CodingTrip - 携程编程大赛 (预赛第一场)- 聪明的猴子
- CodingTrip - 携程编程大赛 (预赛第一场)第二题 括号匹配
- CodingTrip - 携程编程大赛 (预赛第一场) :1002 括号匹配
- 携程编程大赛 (预赛第一场)
- 位图像素的颜色——杭电携程编程大赛 (预赛第二场)
- 携程编程大赛预赛第二场
- CodingTrip - 携程编程大赛-第四题-夺旗
- CodingTrip - 携程编程大赛 (预赛第二场):1001 剪刀石头布
- 携程编程大赛 (预赛第二场)第三题【位图像素的颜色】
- 携程编程大赛 (预赛第二场)第三题【位图像素的颜色】