牛客寒假训练五

记录一次打的最差的一次比赛。(出题人要被一部分的锅,故事背景太没技术含量了)

A 水

#include<bits/stdc++.h>
using namespace std;
 
int main()
{
    int n,m;
    cin>>n>>m;
    string s1;
    string s2;
    cin>>s1>>s2;
    int sum=abs(n-m);
    int c=min(n,m);
    for(int i=0;i<c;i++){
        if(s1[i]!=s2[i]) sum++;
    }
    cout<<sum<<endl;
    return 0;
}

B 牛牛战队的比赛地。

  浮点二分问题,比赛的时候想到二分了,无奈计算几何基础差。

  

#include<bits/stdc++.h>
using namespace std;
const double esp=1e-6;
const int N=1E5+7;
double x[N],y[N];
int n;
bool check(double x1){
    double l=-1e6,r=1e6;
    for(int i=1;i<=n;i++){
        l=max(l,x[i]-sqrt(x1*x1-y[i]*y[i]));
        r=min(r,x[i]+sqrt(x1*x1-y[i]*y[i]));
    }
    return l<=r;
}
int main(){
    cin>>n;
    double l=0,r=100000000,mid,ans=0;
    for(int i=1;i<=n;i++){
        cin>>x[i]>>y[i];
        l=max(l,abs(y[i]));
    }
    while(r-l>=esp){
        mid=(r+l)/2;
        if(check(mid)) r=mid;
        else l=mid;
    }
    printf("%.4lf\n",l);
    return 0;
}

C 模拟题,待补

D 数学题

贪心,设当前位置为A,我们要移动到B,如果第一种方式花费的时间是fabs(A-B),第二种方式应该是fabs(POW(A,1/3)-B)+1.如果第二种

如果第二种方式小,那么就要跳跃,更新一下A=pow(A,1/3)。否则就直接到达B并且退出。

#include<bits/stdc++.h>
using namespace std;
void solve()
{
    double a,b;
    scanf("%lf%lf",&a,&b);
    double p=1.0/3.0;
    double now,ans=0;
    while(1){

        if(a<0) now=-pow(-a,p);
        else now=pow(a,p);

        if(fabs(now-b*1.0)+1.0 < fabs(a-b*1.0)){
            ans+=1.0;
            a=now;
        }
        else{
            ans+=fabs(a-b);
            break;
        }
    }
    printf("%.9lf\n",ans);


}

int main()
{
    int t;
    cin>>t;
    while(t--) solve();

    return 0;
}

E 博弈论,打表找规律,如果是2的整数幂那么Alice赢,否则Bob赢

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
int main()
{
    ll n;
    cin>>n;
    int cnt=0;
    for(int i=0;i<=62;i++){
        if((n>>i)&1) cnt++;
    }
    if(cnt==1) cout<<"Alice"<<endl;
    else cout<<"Bob"<<endl;
    return 0;
}

F 碎碎念。

DP问题,还是要经常练练DP的题目,至少遇到这种简单DP要会写。

首先dp[i][0]表示该状态是AC,dp[i][1]表示该状态是RJ.

如果该状态是dp[i][0],那么上一个状态是dp[i-1][0]或者dp[i-1][1].

即dp[i-1][0]=dp[i-1][1]+dp[i-1][0]

如果该状态是dp[i-1][1],那么上一个状态是AC,因为不可能同时出现两个连续的RJ

因此dp[i][1]=dp[i-k][0]

然后ans[i]=ans[i-1]+dp[i][1]+dp[i][0]。I个问题的答案为二种情况的和。然后再求一下前缀和。

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll mod=1e9+7;
const ll N=1E5+7;
ll dp[N][2];
ll arr[N];
int main()
{
    ll x;
    cin>>x;
    dp[0][0]=1,dp[0][1]=0;
    for(ll i=1;i<=N;i++){
        dp[i][0]=(dp[i-1][0]+dp[i-1][1])%mod;
        if(i>=x) dp[i][1]=dp[i-x][0]%mod;
    }
    for(ll i=1;i<=N;i++){
        arr[i]=dp[i][0]+dp[i][1]+arr[i-1];
        arr[i]%=mod;
    }
    ll m;
    cin>>m;
    while(m--){
        ll l,r;
        cin>>l>>r;
        cout<<(arr[r]-arr[l-1]+mod)%mod<<endl;
    }
    return 0;
}

H hash

题解,,,26进制加法,只需要在原字符串的基础上加上mod计科,无奈相加的时候忘记进位了。。唉

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
ll d[8];
string s;
string s1;
ll f(ll x){
    for(ll i=0;i<=6;i++) d[i]=0;
    ll c=6;
    while(x){
        d[c]=x%26;
        x/=26;
        if(c==1) break;
        c--;
    }
    if(x!=0) return 0;
    s1="";
    for(int i=6;i>=1;i--){
        int c=s[i-1]-'a';
        ll x=d[i]+c;
        while(x>=26){
            x-=26;
            d[i-1]++;
        }
        s1+=('a'+x);
    }
    reverse(s1.begin(),s1.end());
    if(d[0]!=0) return 0;
    return 1;
}
int main(){
    while(cin>>s){
        ll mod;
        cin>>mod;
        if(f(mod)==0)  cout<<-1<<endl;
        else cout<<s1<<endl;
    }
    return 0;
 
}

I 题  签到,题意要毛病??瞎扯??

j题  数学题

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
int main()
{
    ll n;
    double r;
    cin>>n>>r;
    ll i,j;
    cin>>i>>j;
    double l=2*r*sin(M_PI/n);
    ll b=max(i,j);
    ll a=min(i,j);
    ll x=min(b-a,(a-b+n)%n);
    printf("%.6lf\n",x*l);
    return 0;
}

总结:感觉后边这几场比赛大的都不好,可能是心态的原因,也可能是不在状态,但是题意多少都要背一点锅的,还有关于数学跟计算几何的问题不太会.....

猜你喜欢

转载自www.cnblogs.com/Accepting/p/12307256.html