您的位置:首页 > 其它

2014年携程程序设计大赛 预赛第一场 A,B,C

2014-04-11 09:25 357 查看
A.

题解:

反面来想...一个数列如果到不了-1..说明这个数列所有数的最大公约数不是1...所以用B^A-到不了的数目=答案..

Program:

#include<iostream>
#include<algorithm>
#include<stdio.h>
#include<queue>
#include<stack>
#include<map>
#include<set>
#define ll long long
#define oo 1<<29
#define MAXN 100000+5
using namespace std;
ll sum,A,B,P[21]={0,2,3,5,7,11,13,17,19,23};
int gcd(int a,int b)
{
       if (a%b==0) return b;
       return gcd(b,a%b);
}
ll POW(ll p,int k)
{
       ll x=1;
       while (k--) x*=p;
       return x;       
}
void dfs(ll now,ll data,ll num)
{
       ll m=0,j; 
       if (B%data!=0) return;
       for (j=data;j<=B;j++)
          if (j%data==0) m++;
       if (num%2) sum+=POW(m,A);
             else sum-=POW(m,A);
       for (now=now+1;now<=8;now++) 
             dfs(now,data*P[now],num+1);  
}
int main()
{
       ll k,x; 
       freopen("input.txt","r",stdin);
       freopen("output.txt","w",stdout);
       scanf("%I64d",&k);
       while (k--)
       {
               scanf("%I64d%I64d",&A,&B);
               sum=0;
               for (x=1;x<=8;x++) dfs(x,P[x],1);
               printf("%I64d\n",POW(B,A)-sum);
       }
       return 0;
}


B.

题解:

很简单的二位dp..dp[l][r]代表区间[l,r]为一个合法的括号序列所需要加的最少括号..

Program:

#include<iostream>
#include<algorithm>
#include<string.h>
#include<stdio.h>
#include<queue>
#include<stack>
#include<map>
#include<set>
#define ll long long
#define oo 1<<29
#define MAXN 100+5
using namespace std; 
int dp[MAXN][MAXN];
char s[MAXN];
int count(int l,int r)
{
       if (s[l]=='(' && s[r]==')') return 0;
       if (s[l]=='[' && s[r]==']') return 0;
       return 2;
}
int main()
{ 
       int k,len,LEN,x,l,r,i;
       freopen("input.txt","r",stdin);
       freopen("output.txt","w",stdout);
       scanf("%d",&k); 
       while (k--)
       {
               scanf("%s",s+1);
               len=strlen(s+1); 
               memset(dp,0x7f,sizeof(dp)); 
               for (x=1;x<=len;x++) dp[x][x]=1,dp[x+1][x]=0;
               for (LEN=1;LEN<len;LEN++)
                  for (x=1;x<=len-LEN;x++)
                  {
                         l=x,r=x+LEN;
                         dp[l][r]=dp[l+1][r-1]+count(l,r);
                         dp[l][r]=min(dp[l][r],dp[l+1][r]+1); 
                         dp[l][r]=min(dp[l][r],dp[l][r-1]+1);
                         for (i=l;i<r;i++)
                            dp[l][r]=min(dp[l][r],dp[l][i]+dp[i+1][r]);
                  }    
               printf("%d\n",dp[1][len]);
       }
       return 0;
}


C.

题解:

主要是要算下球面距离公式.然后就是裸的最小生成树了.

Program:

#include<iostream>
#include<algorithm>
#include<string.h>
#include<stdio.h>
#include<queue>
#include<cmath>
#include<stack>
#include<map>
#include<set>
#define ll long long
#define oo 1<<29
#define MAXN 100+5
#define eps 1e-5
using namespace std; 
const double pi=3.14159265358979323846;
struct point
{
       double x,y;
}P[MAXN];
double D,L,sum,m,A[MAXN][MAXN];
bool used[MAXN];
double calc(point a,point b)
{
       double ans=(D/2)*acos(sin(a.x)*sin(b.x)+cos(a.x)*cos(b.x)*cos(a.y-b.y));
       return ans;
}
int main()
{ 
       int k,C,t,i,j,x;
       freopen("input.txt","r",stdin);
       freopen("output.txt","w",stdout);
       scanf("%d",&k); 
       while (k--)
       {
              scanf("%lf%lf",&D,&L);
              scanf("%d",&C);
              for (i=1;i<=C;i++)
              {
                     scanf("%lf%lf",&P[i].x,&P[i].y);
                     P[i].x=P[i].x/180*pi;
                     P[i].y=P[i].y/180*pi;
              }
              for (i=1;i<=C;i++)
                for (j=1;j<=C;j++)
                   A[i][j]=calc(P[i],P[j]);
              sum=0;
              memset(used,0,sizeof(used));
              used[1]=true;
              for (t=2;t<=C;t++)
              {
                      m=-1;
                      for (i=1;i<=C;i++)
                        if (used[i])
                          for (j=1;j<=C;j++)
                            if (!used[j])
                               if (A[i][j]<m || m<0) 
                                 m=A[i][j],x=j;
                      sum+=m;
                      used[x]=true;
              }
              if (L>=sum) puts("Y");
                     else puts("N");
       }
       return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: