东大acm预备队第一次双周赛

1 7-1 Lily

题目

在这里插入图片描述
在这里插入图片描述

题目解析

这一题并不难,算是基本的贪心问题(能见缝插针就行 )。

代码

#include <bits/stdc++.h>
using namespace std;

int n;
string s;

int main()
{
    cin>>n>>s;
    for(int i=0;i<s.length();++i)
    {
        if(i==0&&s[i]=='.'&&s[i+1]=='.')
            cout<<'C';
        else if(i!=0&&s[i-1]=='.'&&s[i]=='.'&&s[i+1]=='.'&&i!=s.length()-1)
            cout<<'C';
        else if(i==s.length()-1&&s[i-1]=='.'&&s[i]=='.')
            cout<<'C';
        else
            cout<<s[i];
    }
    return 0;
}

2 7-2 a * b

题目

在这里插入图片描述

题目解析

这一题是高精度乘法,十进制数的乘法和十六进制数的乘法类似,不过是由大于9进位变成了大于15进位。同时还有大于9的数的输出处理。

代码

#include <bits/stdc++.h>
using namespace std;

char at[1005],bt[1005];
int a[1005],b[1005],c[2010];

//将字符转化成数字
int shiji(char c)
{
    if(isdigit(c))
        return c-'0';
    else
        return c-'A'+10;
}

int main()
{
    cin>>at>>bt;
    int lena=strlen(at);
    for(int i=0;i<lena;++i)
        a[i+1]=shiji(at[lena-i-1]);
    
    int lenb=strlen(bt);
    for(int i=0;i<lenb;++i)
        b[i+1]=shiji(bt[lenb-i-1]);
    
    int yu=0;
    for(int i=1;i<=lena;++i)
    {
        yu=0;
        for(int j=1;j<=lenb;++j)
        {
            c[i+j-1]+=a[i]*b[j]+yu;
            yu=c[i+j-1]/16;
            c[i+j-1]%=16;
        }
        c[i+lenb]=yu;
    }

    int lenc=lena+lenb;
    while(c[lenc]==0&&lenc>1)
        lenc--;
    for(int i=lenc;i>=1;--i)
    {
        if(c[i]>=0&&c[i]<=9)
            cout<<c[i];
        else
            cout<<(char)(c[i]-10+'A');  
            //大于9的数字将其转化成十六进制数的字母
    }

    return 0;
}

3 7-3 山头狙击战

题目

在这里插入图片描述
在这里插入图片描述

题目解析

本题考二分答案,需要注意两点:1、初始枪里有一颗子弹,无需换弹时间,便可杀死第一个敌人;2、如果敌人在自己的射程范围外需要等待敌人进入射程才可射击。

代码

#include <bits/stdc++.h>
using namespace std;

const int N=1e6+5;
int n,m,ans,dis[N];

bool check(int x)
{
	//t表示时间
    int t=max(dis[1]-m,0);  //如果第一个敌人在范围外要等待其进入范围
    for(int i=2;i<=n;++i)
    {
        t+=x;  //加上换弹时间
        //初始距离减去时间便是此时敌人和你的距离
        if(dis[i]-t>m)  //如果在射程外等待
            t+=dis[i]-t-m;
        if(dis[i]-t<0) //敌人和你的距离小于0,所给的换弹时间太长了
            return false;
    }
    return true;
}

int main()
{
    cin>>n>>m;
    for(int i=1;i<=n;++i)
        cin>>dis[i];
    sort(dis+1,dis+n+1);  //优先射击最近的敌人
    int L=1;
    int R=dis[n];
    while(L<=R)
    {
        int M=(L+R)/2;
        if(check(M))
        {
            ans=M;
            L=M+1;
        }
        else
         R=M-1;
    }
    cout<<ans<<endl;
    return 0;
}

4 7-4 Reversing Linked List

题目

在这里插入图片描述
在这里插入图片描述

题目解析

一个关于链表翻转的题目,难点在于英文读懂题目,以及翻转过程中思路的清晰,本题数据中还有孤立节点的出现,所以我们还需统计真实连接的节点数目。本题作者用单向链表实现,如果用双向链表实现会更简单。

代码

#include <bits/stdc++.h>
using namespace std;

const int MAX=1e5+5;
struct node
{
    int data,next_adress;
}nd[MAX];
int st_adress,N,K,adress,cnt;

int main()
{
    cin>>st_adress>>N>>K;
    for(int i=1;i<=N;++i)
    {
        cin>>adress;
        cin>>nd[adress].data>>nd[adress].next_adress;
    }

    int a=st_adress;
    while(a!=-1)  //统计真实节点数目
    {
        cnt++;
        a=nd[a].next_adress;
    }

    a=st_adress;
    for(int i=1;i<=cnt/K;++i) //实现链表翻转过程
    {
        int pre=a;
        int cur=nd[pre].next_adress;
        int tail,tmp;
        int sum=1;
        while(sum<K)
        {
            tmp=nd[cur].next_adress;
            nd[cur].next_adress=pre;
            pre=cur;
            cur=tmp;
            sum++;
        }
        nd[a].next_adress=cur;
        if(i==1)
            st_adress=pre;
        else
            nd[tail].next_adress=pre;
        tail=a;
        a=cur;
    }
    a=st_adress;
    while(a!=-1)
    {
        if(nd[a].next_adress!=-1)
            printf("%05d %d %05d\n",a,nd[a].data,nd[a].next_adress);
        else
            printf("%05d %d %d\n",a,nd[a].data,nd[a].next_adress);
        a=nd[a].next_adress;
    }
    return 0;
}

5 7-5 一元三次方程

题目

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

题目解析

二分答案,注意一点便是求导求出单调区间。

代码

#include <bits/stdc++.h>
using namespace std;

const double eps = 1e-7;
int T;
double a, b, c, d, p, q;

double jisuan(double x)
{
    return a * x * x * x + b * x * x  +c * x + d;
}

void func(double L, double R)
{
    while (R - L > eps)
    {
        double M = (L + R) / 2;
        if (jisuan(L) * jisuan(M) <= 0)
            R = M;
        else
            L = M;
        if (jisuan(M) * jisuan(R) <= 0)
            L = M;
        else
            R = M;
    }
    printf("%.6f ", L);
}

int main()
{
    cin >> T;
    while (T--)
    {
        cin >> a >> b >> c >> d >> p >> q;
        double t1 = min((-2 * b + sqrt(4 * b * b - 12 * a * c)) / (6 * a), (-2 * b - sqrt(4 * b * b - 12 * a * c)) / (6 * a));
        double t2 = max((-2 * b + sqrt(4 * b * b - 12 * a * c)) / (6 * a), (-2 * b - sqrt(4 * b * b - 12 * a * c)) / (6 * a));
        func(p, t1);
        func(t1, t2);
        func(t2, q);
    }
    return 0;
}

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

谷神星ceres

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值