SMU寒假训练周报4

1.网络寻路

原题链接:P8605 [蓝桥杯 2013 国 AC] 网络寻路 - 洛谷

这题做过但还是误会题意了,题目严格要求当且仅当深度为3的路才会被记录,我以为是大于等于3。。所以记录一个头结点,在深度为二时遍历计数即可

查看代码

#include<bits/stdc++.h>
using namespace std;
#define int long long
vector<int>v[1000000];
int sign[10010];
int ans=0;
void dfs(int tou,int x,int deep)
{
    if(deep==2)
    {
        for(int i=0;i<v[x].size();i++)
        {
            if(v[x][i]==tou||!sign[v[x][i]])ans++;
        }
        return;
    }
    for(int i=0;i<v[x].size();i++)
    {
        if(!sign[v[x][i]])
        {
            sign[v[x][i]]=1;
            dfs(tou,v[x][i], deep + 1);
            sign[v[x][i]]=0;
        }
    }
}
signed main()
{
    ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
    int n,m;
    cin>>n>>m;
    for(int i=1;i<=m;i++)
    {
        int x,y;
        cin>>x>>y;
        v[x].push_back(y);
        v[y].push_back(x);
    }
    for(int i=1;i<=n;i++)
    {
        //memset(sign,0,sizeof sign);
        sign[i]=1;
        dfs(i,i,0);
        sign[i]=0;
    }
    cout<<ans;
    return 0;
}

2.宝石组合

原题链接:P10426 [蓝桥杯 2024 省 B] 宝石组合 - 洛谷

化简之后得知实际是求gcd(a,b,c),根据定义可得所找的就是三个数中最大的公共因数,因此我们令 v[i] 数组为有哪些数包含因数 i,在处理后我们只需要从大到小遍历所有因数,找到首个 v[i] 的长度大于 3 的数即为答案(意义为在给出的数组中有大于等于 3 个数的其中一个因数为 i),其中包含的三个数的具体数值即为我们要找的答案,题目中要求字典序最小,故在此之前对数组进行排序即可

查看代码
 #include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 100010;
vector<int> v[N];
int a[N];
int main()
{
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
 
    int n;
    cin >> n;
    for(int i = 1;i<=n;i++){
        cin >> a[i];
    }
    sort(a+1,a+1+n);
    for(int i = 1;i<=n;i++){
        for(int j = 1;j * j <= a[i];j++){
            if(a[i] % j == 0){
                if(v[j].size() < 3){
                    v[j].push_back(a[i]);
                }
 
                if(j * j < a[i] && v[a[i]/j].size() < 3){
                    v[a[i]/j].push_back(a[i]);
                }
            }
        }
    }
    for(int i = 100000;i>=1;i--){
        if(v[i].size() == 3){
            cout << v[i][0] << " " << v[i][1] << " " << v[i][2] << endl;
            break;
        }
    }
    return 0;
}

3.环境治理

原题链接:P8794 [蓝桥杯 2022 国 A] 环境治理 - 洛谷

这个题大意了,其实已经用floyd写出来了,但是没考虑到其实一条路的灰尘度和其所连的两个点都有关系,只考虑了一个点哎,就是最短路和二分的结合

查看代码
 #include<bits/stdc++.h>
using namespace std;
#define int long long
int n,q;
int a[1010][1010],b[1010][1010];
int f[1010][1010],p[1010][1010];
int dis[1000000];
bool check(int x)
{
    for(int i=1;i<=n;i++)
    {
        for(int j=1;j<=n;j++)
        {
            f[i][j]=a[i][j];
        }
    }
    int y=x/n;
    int z=x%n;
    for(int i=1;i<=n;i++)dis[i]=y;
    for(int i=1;i<=z;i++)dis[i]++;
    for(int i=1;i<=n;i++)
    {
        for(int j=1;j<=n;j++)
        {
            f[i][j]-=dis[i]+dis[j];
            f[i][j]=max(f[i][j],b[i][j]);
        }
    }
    for (int i = 1; i <= n; i++) {
        for (int j = 1; j <= n; j++) {
            for (int k = 1; k <= n; k++) {
                f[j][k] = min(f[j][k], f[j][i] + f[i][k]);
            }
        }
    }
    int sum=0;
    for(int i=1;i<=n;i++)
    {
        for(int j=1;j<=n;j++)
        {
            sum+=f[i][j];
        }
    }
    return sum>q;
}
signed main()
{
    //ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);

    cin>>n>>q;
    for(int i=1;i<=n;i++)
    {
        for(int j=1;j<=n;j++)
        {
            cin>>a[i][j];
        }
    }
    for(int i=1;i<=n;i++)
    {
        for(int j=1;j<=n;j++)
        {
            cin>>b[i][j];
        }
    }
    int l=0,r=1e7;
    int ans=1e9;
    while(l<=r)
    {
        int mid=l+r>>1;
        if(check(mid))l=mid+1;
        else r=mid-1,ans=mid;
    }
    if(ans==1e9)cout<<-1;
    else cout<<ans;
    //cout<<l;
    return 0;
}

4.拔河

原题链接:P10429 [蓝桥杯 2024 省 B] 拔河 - 洛谷

其实只需要把所有范围都算出来,排序后找出相邻差值最小的一组即可了

查看代码
 #include<bits/stdc++.h>
using namespace std;
#define int long long
int a[1000000];
signed main()
{
    //ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
    int n;
    cin>>n;
    for(int i=1;i<=n;i++)cin>>a[i];
    vector<int>v;
    for(int i=1;i<=n;i++)
    {
        int sum=0;
        for(int j=i;j<=n;j++)
        {
            sum+=a[j];
            v.push_back(sum);
        }
    }
    sort(v.begin(),v.end());
    int mi=LLONG_MAX;
    for(int i=1;i<v.size();i++)
    {
        int t=v[i]-v[i-1];
        mi=min(mi,t);
    }
    cout<<mi;
    return 0;
}
posted @ 2025-02-23 19:02  伊芙加登  阅读(12)  评论(0)    收藏  举报