首页 > 代码库 > 360笔试(3-18)编程题

360笔试(3-18)编程题

1.给一个半径为R的圆,圆心是(0,0),开始位于(R,0),分别求从始点顺时针和逆时针走长度为L的终点坐标

 有可能走多圈,先处理成走一圈的形式,然后判是不是四个断点,如果是则输出

  然后把L处理到第一象限,与x轴形成的夹角是L/R,y点坐标就是R*sin(L/R),那么x=sqrt(R*R-x*x)

技术分享
#include<bits/stdc++.h>using namespace std;typedef long long ll;const int maxn=1e5+5;const double pi=acos(-1);const double esp=1e-8;double L,R,S;void solve(double &x,double& y,double l){    double jiao=(l/S)*pi*2;    y=R*sin(jiao);    x=sqrt(R*R-y*y);}int main(){    cin>>L>>R;    S=pi*R*2;    while(L>=S)L-=S;            //先判断四个端点    if(abs(L)<=esp){        printf("%.3f %.3f\n",R,0);        printf("%.3f %.3f\n",R,0);        return 0;    }    else if(abs(L-(S/4))<=esp){        printf("%.3f %.3f\n",0,R);        printf("%.3f %.3f\n",0,-R);        return 0;    }    else if(abs(L-(S/4)*2)<=esp){        printf("%.3f %.3f\n",-R,0);        printf("%.3f %.3f\n",-R,0);        return 0;    }    else if(abs(L-(S/4)*3)<=esp){        printf("%.3f %.3f\n",0,-R);        printf("%.3f %.3f\n",0,R);        return 0;    }        // 假设顺时针的话,然后判断在哪个象限    double x,y;        if(L<(S/4)){        solve(x,y,L);    }    else if(L<(S/2)){        L=S/2-L;        solve(x,y,L);        x*=-1;    }    else if(L<(S/4)*3){        L-=S/2;        solve(x,y,L);        x*=-1;y*=-1;    }    else{        L=S-L;        solve(x,y,L);        y*=-1;    }        printf("%.3f %.3f\n",x,-y);    printf("%.3f %.3f\n",x,y);                return 0;}
View Code

2.给一个长度是n的串,串中只有1-9这9个数字,求把这个串拆分若干个字串,每个字串中没有重复的数字,输出有多少种分割方法,答案mod1000000007

做选择做的有点紧张,读错题了,简单dp,dp[i]表示分割前i个的种类,如果从j分割,那么j以及前面的是一个分割方法,(j+1)-i是一个分割,那么dp[i]=sigma(dp[j])j表示从i往回走,能走到的无重复的最远距离

简单题,血亏

技术分享
#include<cstdio>#include<cstring>#include<iostream>using namespace std;typedef long long ll;const int maxn=1e5+5;const int mod=1000000007;int a[maxn],v[10];int dp[maxn];int main(){    //freopen("in.txt","r",stdin);    int n;    scanf("%d",&n);    for(int i=1;i<=n;i++)scanf("%d",a+i);    dp[0]=1;    for(int i=1;i<=n;i++){        for(int j=i-1;j>=0;j--){            if(v[a[j+1]])break;            v[a[j+1]]=1;            dp[i]=(dp[i]+dp[j])%mod;        }        memset(v,0,sizeof(v));    }    printf("%d\n",dp[n]);    return 0;}
View Code

3.有一个双端队列,两个海盗分金子,每人轮流在取一个金子,可以在左端或者右端每次取一个金子,两人都会做最有选泽,输出先手和后手的得到的最多金子

博弈dp,记忆化搜索就能解,dp[i][j][2],表示i-j之间,第一个人个第二个人能得到的最佳答案

#include<bits/stdc++.h>using namespace std;typedef long long ll;const int maxn=505;int a[maxn];int dp[maxn][maxn][2];typedef pair<int,int> pr;int t,n;void dfs(int l,int r,int cnt){    if(dp[l][r][cnt]!=-1)return ;    if(l==r){        dp[l][r][cnt]=a[l];        dp[l][r][cnt^1]=0;        return ;    }    dfs(l+1,r,cnt^1);    dfs(l,r-1,cnt^1);    int L=dp[l+1][r][cnt]+a[l],R=dp[l][r-1][cnt]+a[r];    //cout<<l<<" "<<r<<" "<<L<<" "<<R<<endl;    if(L>R){        dp[l][r][cnt]=L;        dp[l][r][cnt^1]=dp[l+1][r][cnt^1];    }    else{        dp[l][r][cnt]=R;        dp[l][r][cnt^1]=dp[l][r-1][cnt^1];    }}int main(){    //freopen("in.txt","r",stdin);    int cas=1;    cin>>t;    while(t--){        cin>>n;        for(int i=0;i<n;i++)cin>>a[i];        memset(dp,-1,sizeof(dp));        dfs(0,n-1,0);                printf("Case #%d: %d %d\n",cas++,dp[0][n-1][0],dp[0][n-1][1]);    }    return 0;}

 

360笔试(3-18)编程题