8_15 小测
第1题 Coprime

输入格式

输出格式

思路:
我们知道互质的两个数的因数除1外都不相同,多个数也一样。所以我们可以枚举因数的倍数,在用数组计数计算有多少个数的因数是这个因数。如果个数大1那就和两两互质无关,如果个数等于n那就和两两集合无关了。
代码:
#include<bits/stdc++.h>
using namespace std;
int n,a[1000005],c[1000005];
int main(){
scanf("%d",&n);
for(int i=1;i<=n;i++)
{
scanf("%d",&a[i]);
c[a[i]]++;//数组计数
}
bool d=1,f=1;
for(int i=2;i<=1000000;i++)
{
int t=0;
for(int j=i;j<=1000000;j=j+i)
{
t=t+c[j];//累加个数
}
if(t>1)d=0;//和两两互质无关
if(t==n)f=0;//和集合互质无关
}
if(d)printf("pairwise coprime");
else if(f)printf("setwise coprime");
else printf("not coprime");
return 0;
}
第2题 旅游

输入格式

输出格式

思路:
当看到城市之间有n-1条道路的时候我们可以想到树,因为树上s~t的路径一定,用LCA算出即可。但有k个传送门,于是我们可以求出离s最近的传送门距离和离t最近的传送门距离的和与s~t的路径长度取个最小即答案。
代码:
#include<bits/stdc++.h>
using namespace std;
long long n,T,m,q,op[2000005],num,f[2000005][25],d[2000005];
vector<int>a[2000005];
inline void solve()
{
queue<long long>q;
for(int i=1;i<=m;i++)
{
int x;
cin>>x;
q.push(x);
op[x]=0;
}
while(!q.empty())
{
int u=q.front();
q.pop();
for(int i=0;i<a[u].size();i++)
{
int v=a[u][i];
if(op[v]!=-1)continue;
op[v]=op[u]+1;
q.push(v);
}
}
}
void dfs(int x,int fa)
{
f[x][0]=fa;
d[x]=d[fa]+1;
for(int i=1;i<=20&&f[f[x][i-1]][i-1]; i++)
{
f[x][i]=f[f[x][i-1]][i-1];
}
for(int i=0;i<a[x].size();i++)
{
if(a[x][i]!=fa)
{
dfs(a[x][i], x);
}
}
}
int lca(int x, int y)
{
if(d[x]<d[y]) swap(x, y);
for(int i=20;i>=0;i--)
{
if(d[f[x][i]] >= d[y])
{
x=f[x][i];
}
}
if(x==y)return x;
for(int i=20;i>=0; i--)
{
if(f[x][i]!=f[y][i])
{
x=f[x][i];
y=f[y][i];
}
}
return f[x][0];
}
int main(){
cin>>n>>m>>q;
for(int i=1;i<=n;i++)
{
op[i]=-1;
}
for(int i=1;i<n;i++)
{
int u,v;
cin>>u>>v;
a[u].push_back(v);
a[v].push_back(u);
}
dfs(1, 0);
solve();
while(q--)
{
int x,y;
cin>>x>>y;
int LCA=lca(x, y);
cout<<min(d[x]-d[LCA]+d[y]-d[LCA],(op[x]==-1 || op[y]==-1)?LLONG_MAX:op[x]+op[y])<<"\n";
}
return 0;
}
第3题 考试

输入格式

输出格式

思路:
观察题目我们可以发现如果B<A时加B肯定更好,所以我们可以枚举最后的课程的天数,算出将最后的课程的天数压倒枚举的数最小的不愉快度的最小值就是答案。
代码:
#include<bits/stdc++.h>
using namespace std;
unsigned long long a,b,A,B,C,n,m,bb[100005],aa[100005],aaa,bbb;
int main(){
scanf("%llu%llu%llu",&A,&B,&C);
scanf("%llu%llu",&n,&m);
for(int i=1;i<=n;i++)
{
scanf("%llu",&a);
aa[a]++;
aaa+=a;
}
for(int i=1;i<=m;i++)
{
scanf("%llu",&b);
bb[b]++;
bbb+=b;
}
unsigned long long y=LLONG_MAX,p1=0,p2=0,s1=bbb,s2=m,s3=aaa,s4=n;
for(int i=100000;i>=1;i--)//枚举最后的课程的天数
{
p1+=1ull*i*bb[i];
p2+=bb[i];
s1-=1ull*i*bb[i];
s2-=bb[i];
s3-=1ull*i*aa[i];
s4-=aa[i];
if(p2==0)continue;
unsigned long long t=0;
if(A<B)
{
t=t+min(p1-p2*i,s2*i-s1)*A;
if(p1-p2*i-min(p1-p2*i,s2*i-s1))t=t+(p1-p2*i-min(p1-p2*i,s2*i-s1))*B;
}
else
{
t=t+(p1-p2*i)*B;
}
t=t+(s4*i-s3)*C;
y=min(y,t);
}
printf("%llu",y);
return 0;
}

浙公网安备 33010602011771号