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

浙公网安备 33010602011771号