AcWing 第 87 场周赛 ABC

https://www.acwing.com/activity/content/competition/problem_list/2814/

4797. 移动棋子

#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
typedef pair<LL,LL> PII;
const LL MAXN=1e18;
const LL N=1e6+10,M=4002;
const double PI=3.1415926535;
#define endl '\n'
int a[M][M];
int main()
{
    cin.tie(0); cout.tie(0); ios::sync_with_stdio(false);
    LL T=1;
    //cin>>T;
    while(T--)
    {
        LL x=-1,y=-1;
        for(int i=1;i<=5;i++)
        {
            for(int j=1;j<=5;j++)
            {
                cin>>a[i][j];
                if(a[i][j]==1) x=i,y=j;
            }
        }
        cout<<abs(x-3)+abs(y-3);
    }
    return 0;
}

4798. 打怪兽

题目大意:

n个怪兽,每个怪兽的防御值为 ai 。我的初始攻击力为 m 。 

当攻击力大于 0 时,可以发动攻击: 任意选择 1∼2 个怪兽,并消耗 x 点法力值,对每个所选怪兽发动一次伤害为 x 的攻击。

对于受到攻击的怪兽,如果其防御值小于或等于 x,则会被消灭。否则,它将免疫此次攻击,不受任何影响。

请你确定最大的整数 k,满足:通过合理安排攻击,可以将第 1∼k 个怪兽全部消灭。
输入样例1:
5 7
2 3 5 4 1
输出样例1:
3

二分+贪心
因为这个题目的数据范围只在1000之内,所以二分+贪心是没有问题的(nlog^2n),不会爆时间

#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
typedef pair<LL,LL> PII;
const LL MAXN=1e18;
const LL N=1e6+10,M=4002;
const double PI=3.1415926535;
#define endl '\n'
LL n,m,a[N],b[N];
bool check(LL x)
{
    for(int i=1;i<=x;i++)
        b[i]=a[i];
    sort(b+1,b+1+x);
    reverse(b+1,b+1+x);
    LL res=0;
    for(int i=1;i<=x;i++)
    {
        res+=b[i];
        i++;
    }
    if(res<=m) return true;
    else return false;
}
int main()
{
    cin.tie(0); cout.tie(0); ios::sync_with_stdio(false);
    LL T=1;
    //cin>>T;
    while(T--)
    {
        cin>>n>>m;
        for(int i=1;i<=n;i++)
        {
            cin>>a[i];
        }
        LL l=1,r=n,ans=0;
        while(l<=r)
        {
            LL mid=(l+r)/2;
            if(check(mid)==false) r=mid-1;
            else
            {
                ans=mid;
                l=mid+1;
            }
        }
        cout<<ans<<endl;
    }
    return 0;
}

4799. 最远距离

题目大意:

如果一个无向连通图满足去掉其中的任意一条边都会使得该图变得不连通,则称该图为有效无向连通图。

 n个点 m 条边的有效无向连通图,点的编号为 1∼n,所有边的长度均为 1。 

求给定图中距离最远的两个点之间的距离。
输入样例1:
4 3
1 2
1 3
1 4
输出样例1:
2

树的直径板子题

详解见代码内部

/*
由题目已知条件可得知:
如果一个无向连通图满足去掉其中的任意一条边都会使得该图变得不连通,
则称该图为有效无向连通图
即为这所有的点都是由边连起来了成为了一棵树
我们要求最长的路径即求树的最长直径
*/
#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
typedef pair<LL,LL> PII;
const LL MAXN=1e18;
const LL N=1e6+10,M=4002;
const double PI=3.1415926535;
#define endl '\n'
LL n,m,ans=0;
LL e[N],ne[N],h[N],idx;
void add(LL a,LL b)
{
    e[idx]=b,ne[idx]=h[a],h[a]=idx++;
}
LL dfs(LL u,LL father)
{
    LL dist=0;//表示从当前点往下走的最大长度
    LL d1=0,d2=0;
    for(int i=h[u];i!=-1;i=ne[i])
    {
        LL j=e[i];
        if(j==father) continue;//不能往回搜啦
        LL d=dfs(j,u)+1;
        dist=max(dist,d);

        if(d>=d1) d2=d1,d1=d;
        else if(d>d2) d2=d;
    }
    ans=max(ans,d1+d2);
    return dist;
}
int main()
{
    cin.tie(0); cout.tie(0); ios::sync_with_stdio(false);
    LL T=1;
    //cin>>T;
    while(T--)
    {
        memset(h,-1,sizeof h);
        cin>>n>>m;
        for(int i=1;i<=m;i++)
        {
            LL a,b;
            cin>>a>>b;
            //建边
            add(a,b);
            add(b,a);
        }
        dfs(1,-1);//当前节点,前一个节点
        cout<<ans<<endl;
    }
    return 0;
}
posted @ 2023-01-22 17:03  Vijurria  阅读(6)  评论(0编辑  收藏  举报