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;
}