青岛农业大学2023年第一次训练赛题解

A题

正常输出就可以

#include<bits/stdc++.h>
int main()
{
    std::cout << "鸡你太美" << std::endl;
    return 0;
}

B题

就是输入三个数,求平均值 

#include<bits/stdc++.h>
int main()
{
    int sum = 0;
    for (int i = 0; i < 3; i ++)
    {
        int a;
        std::cin >> a;
        sum += a;
    }
    std::cout << sum / 3 << std::endl;
    return 0;
}

C题

输入一个字符串,找出"rap"的个数

遍历一遍字符串即可求出

#include<bits/stdc++.h>
std::string s;
int cnt;
int main()
{
    std::cin >> s;
    for (int i = 0; i < s.size() - 2; i ++)
    {
        if (s.substr(i, 3) == "rap")
        {
            cnt ++;
        }
    }
    std::cout << cnt << std::endl;
    return 0;
} 

D题

该题用到了基础算法二分。

check函数:

先保证每个数不会大于mid。

然后如果该组加上当前数大于mid,就需要重新开个组,将该数放入这个新组中,否则可以直接加入原组中。

最后判断组数是否符合要求。

#include<bits/stdc++.h>
const int N = 1e5 + 10;
typedef long long LL;
LL a[N];
LL maxn, minn;
int n, m;
bool check(LL x)
{
    LL sum = 0;
    LL res = 0;
    for (int i = 0; i < n; i ++)
    {
        if (a[i] > x)
            return false;
        if (sum + a[i] > x)
        {
            sum = a[i];
            res ++;
        }
        else
            sum += a[i];
    }
    if (sum)
        res ++;
    if (res <= m)
        return true;
    else
        return false;
}
int main()
{
    std::cin >> n >> m;
    for (int i = 0; i < n; i ++)
    {
        std::cin >> a[i];
    }
    LL l = 0;
    LL r = 1e10;
    while (l < r)
    {
        LL mid = l + r >> 1;
        if (check(mid))
            r = mid;
        else
            l = mid + 1;
    }
    std::cout << r << std::endl;
    return 0;
}

E题

用到了基础图论算法dijkstra。

顺着箭头的权值是1,其他的情况都是0。

然后用dijkstra求一遍从1到n的最短路即可。

存邻接表的时候可以用map存下来每条的边是第几个,方便后续更改边的权值。

#include<bits/stdc++.h>
#define x first
#define y second
const int N = 1e6 + 10;
const int INF = 0x3f3f3f3f;
typedef std::pair<int, int> PII;
int h[N], e[N], ne[N], w[N], idx;
int dist[N];
bool st[N];
std::map<PII, int> mp;
int n, m, q;
void add(int a, int b, int c)
{
    mp[{a, b}] = idx;
    e[idx] = b;
    ne[idx] = h[a];
    w[idx] = c;
    h[a] = idx ++;
}
void dijkstra()
{
    memset(dist, 0x3f, sizeof dist);
    dist[1] = 0;
    std::priority_queue<PII, std::vector<PII>, std::greater<PII>> heap;
    heap.push({0, 1});
    while (heap.size())
    {
        auto t = heap.top();
        heap.pop();
        int ver = t.y, distance = t.x;
        if (st[ver]) continue;
        st[ver] = true;
        for (int i = h[ver]; ~i; i = ne[i])
        {
            int j = e[i];
            if (dist[j] > distance + w[i])
            {
                dist[j] = distance + w[i];
                heap.push({dist[j], j});
            }
        }
    }
}
int main()
{
    std::cin >> n >> m;
    memset(h, -1, sizeof h);
    for (int i = 0; i < m; i ++)
    {
        int a, b;
        std::cin >> a >> b;
        add(a, b, 0);
        add(b, a, 0);
    }
    std::cin >> q;
    for (int i = 0; i < q; i ++)
    {
        int a, b;
        std::cin >> a >> b;
        w[mp[{a, b}]] = 1;
    }
    dijkstra();
    if (dist[n] == INF) puts("How about we explore the area ahead of us later?");
    else std::cout << dist[n] << std::endl;
    return 0;
}

F题

防AK。

题解待补

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

const long double eps=1e-9;
const long double PI=acos(-1);

struct Point
{
    long double x,y;

    Point()=default;
    Point(long double x,long double y): x(x),y(y) {}

    bool operator==(const Point &a) const {return (abs(x-a.x)<=eps && abs(y-a.y)<=eps);}
    Point operator+(const Point &a) const {return Point(x+a.x,y+a.y);}
    Point operator-(const Point &a) const {return Point(x-a.x,y-a.y);}
    Point operator-() const {return Point(-x,-y);}
    Point operator*(const long double &k) const {return Point(k*x,k*y);}
    Point operator/(const long double &k) const {return Point(x/k,y/k);}
    long double operator*(const Point &a) const {return x*a.x+y*a.y;} //Dot
    long double operator^(const Point &a) const {return x*a.y-y*a.x;} //Cross
    bool operator<(const Point &a) const {if (abs(x-a.x)<=eps) return y<a.y-eps; return x<a.x-eps;}
    bool is_par(const Point &a) const {return abs((*this)^a)<=eps;}
    bool is_ver(const Point &a) const {return abs((*this)*a)<=eps;}
    int toleft(const Point &a) const {auto t=(*this)^a; return (t>eps)-(t<-eps);}
    long double len() const {return sqrt((*this)*(*this));}
    long double dis(const Point &a) const {return (a-(*this)).len();}
    long double ang(const Point &a) const {return acos(((*this)*a)/(this->len()*a.len()));}
    //Point rot(const long double &rad) const {return Point(x*cos(rad)-y*sin(rad),x*sin(rad)+y*cos(rad));}
    Point rot(const long double &sinr) const
    {
        const long double cosr=sqrt(1-sinr*sinr);
        return Point(x*cosr-y*sinr,x*sinr+y*cosr);
    }
};

struct Line
{
    Point p,v; //p+tv

    Line()=default;
    Line(Point p,Point v): p(p),v(v) {}

    bool operator==(const Line &a) const {return (v.is_par(a.v) && v.is_par(p-a.p));}
    bool is_par(const Line &a) const {return (v.is_par(a.v) && !v.is_par(p-a.p));}
    bool is_ver(const Line &a) const {return v.is_ver(a.v);}
    bool is_on(const Point &a) const {return v.is_par(a-p);}
    int toleft(const Point &a) const {return v.toleft(a-p);}
    Point inter(const Line &a) const {return p+v*((a.v^(p-a.p))/(v^a.v));}
    long double dis(const Point &a) const {return abs(v^(a-p))/v.len();}
    Point proj(const Point &a) const {return p+v*((v*(a-p))/(v*v));}
};

int n,x,y;
vector<Point> p;

using Ans=tuple<bool,Point,Point,Point,Point>;
const Ans _false={false,Point(0,0),Point(0,0),Point(0,0),Point(0,0)};

Ans check(long double d,Line u,Line v)
{
    vector<Point> pr;
    for (auto a:p)
    {
        if (u.toleft(a)*v.toleft(a)<=0) continue;
        pr.push_back(u.proj(a));
    }
    if (pr.empty()) pr.push_back(u.p);
    if (pr.size()==1) pr.push_back(pr[0]+u.v/u.v.len()*d);
    sort(pr.begin(),pr.end());
    auto al=pr.front(),ar=pr.back();
    if ((ar-al)*u.v<-eps) swap(al,ar);
    if (al.dis(ar)>d+eps) return _false;
    ar=al+u.v/u.v.len()*d;
    auto _v=Point(-u.v.y,u.v.x);
    Line p(al,_v),q(ar,_v);
    return {true,u.inter(p),u.inter(q),v.inter(q),v.inter(p)};
}

Ans check(long double d,Point a,Point b)
{
    auto v=a-b;
    if (a.dis(b)<=d+eps)
    {
        v=Point(-v.y,v.x);
        return check(d,Line(a,v),Line(b,v));
    }
    long double sinr=d/a.dis(b);
    auto _v=v.rot(sinr);
    auto t=check(d,Line(a,_v),Line(b,_v));
    if (t!=_false) return t;
    _v=v.rot(-sinr);
    t=check(d,Line(a,_v),Line(b,_v));
    return t;
}

Ans check(long double d)
{
    for (int i=0;i<n;i++)
    {
        for (int j=0;j<i;j++)
        {
            auto t=check(d,p[i],p[j]);
            if (t!=_false) return t;
        }
    }
    return _false;
}

int main()
{
    scanf("%d",&n);
    for (int i=1;i<=n;i++)
    {
        scanf("%d%d",&x,&y);
        p.push_back(Point(x,y));
    }
    long double l=0.5,r=100000;
    while (r-l>1e-12)
    {
        long double mid=(l+r)/2;
        if (check(mid)!=_false) r=mid;
        else l=mid;
    }
    //auto [ok,a,b,c,d]=check(r);
    //cout<<fixed<<setprecision(12)<<a.x<<' '<<a.y<<endl;
    //cout<<fixed<<setprecision(12)<<b.x<<' '<<b.y<<endl;
    //cout<<fixed<<setprecision(12)<<c.x<<' '<<c.y<<endl;
    //cout<<fixed<<setprecision(12)<<d.x<<' '<<d.y<<endl;
    printf("%.12Lf\n",r);
    getchar(); getchar();
    return 0;
}

  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值