Contest2822 - 2021个人训练赛第12场 19272 Problem H 找朋友
题目描述
Bob 和他的好朋友们手拉手在一起围成了一个圈,给出每条边的权值,定义任意两个人的距离为他们之间的权值总和乘上他们的边数(由于成环,左右都可以走,取小的作为距离)。输入 k 组朋友,输出他们之间的距离分别是多少。
输入
输入第一行为 n,代表总共有 n 个小朋友(编号为 1~n)。
输入第二行有 n 个非负整数,第一个代表 1 号和 2 号的距离,第二个代表 2 号和 3号的距离,第 n 个代表 n 号和 1 号的距离。
输入第三行为 k,代表总共有 k 组查询。
接下来 k 行,每行有两个小于 n 的整数 x 和 y,代表查询 x 和 y 之间的距离。(x和 y 可能相同)
输入第二行有 n 个非负整数,第一个代表 1 号和 2 号的距离,第二个代表 2 号和 3号的距离,第 n 个代表 n 号和 1 号的距离。
输入第三行为 k,代表总共有 k 组查询。
接下来 k 行,每行有两个小于 n 的整数 x 和 y,代表查询 x 和 y 之间的距离。(x和 y 可能相同)
输出
共 k 行,每行一个数字,代表小朋友之间的距离。
样例输入 Copy
【样例1】
5
84 43 1 96 63
1
1 4
【样例2】
5
91 92 27 54 46
1
2 2
【样例3】
5
98 41 53 65 76
1
3 2
样例输出 Copy
【样例1】
318
【样例2】
0
【样例3】
41
提示
样例 1:对于 1 号和 4 号小朋友,最短距离应该是 4->5->1 (96+63)*2=318
因为 1->2->3->4 (84+43+1)*3=384 取 318
样例 2:对于 2 号和 2 号小朋友,最短距离应该是 0
样例 3:对于 3 号和 2 号小朋友,最短距离应该是 3->2 41
对于 30% 的数据,满足 n<=5, k=1
对于 50% 的数据,满足 n<=10, k<=10
对于 70%的数据,满足 n<=100, k<=100
对于 100% 的数据,满足 n<=10000, k<=1000000
因为 1->2->3->4 (84+43+1)*3=384 取 318
样例 2:对于 2 号和 2 号小朋友,最短距离应该是 0
样例 3:对于 3 号和 2 号小朋友,最短距离应该是 3->2 41
对于 30% 的数据,满足 n<=5, k=1
对于 50% 的数据,满足 n<=10, k<=10
对于 70%的数据,满足 n<=100, k<=100
对于 100% 的数据,满足 n<=10000, k<=1000000
C代码参考:
#include<stdio.h>
int main()
{
long int n,k,i,x,y,t,num,sum1=0,sum2=0,a[100005];
a[0]=0;
scanf("%lld",&n);
for(i=1;i<=n;i++){
scanf("%lld",&num);
a[i]=a[i-1]+num;
}
scanf("%lld",&k);
for(i=1;i<=k;i++)
{
scanf("%lld%lld",&x,&y);
if(x>y)
{
t=x;
x=y;
y=t;
}
sum1=(a[y-1]-a[x-1])*(y-x);
sum2=(a[n]-(a[y-1]-a[x-1]))*(n-(y-x));
if(sum1<sum2)
printf("%lld\n",sum1);
else
printf("%lld\n",sum2);
}
return 0;
}
int main()
{
long int n,k,i,x,y,t,num,sum1=0,sum2=0,a[100005];
a[0]=0;
scanf("%lld",&n);
for(i=1;i<=n;i++){
scanf("%lld",&num);
a[i]=a[i-1]+num;
}
scanf("%lld",&k);
for(i=1;i<=k;i++)
{
scanf("%lld%lld",&x,&y);
if(x>y)
{
t=x;
x=y;
y=t;
}
sum1=(a[y-1]-a[x-1])*(y-x);
sum2=(a[n]-(a[y-1]-a[x-1]))*(n-(y-x));
if(sum1<sum2)
printf("%lld\n",sum1);
else
printf("%lld\n",sum2);
}
return 0;
}
或:
#include<stdio.h>
int main(){
long long int n,k,i,x,y,t,sum1=0,sum2=0,sum=0,a[10000];
scanf("%lld",&n);//有n个小朋友
for(i=0;i<n;i++){//输入每个小朋友之间的距离
scanf("%lld",&a[i]);
}
scanf("%lld",&k);//输入k,有k组查询
for(i=0;i<k;i++){//输入x与y(k行)
scanf("%lld%lld",&x,&y);
if(x>y){//保证输入的x比y要小
t=x;
x=y;
y=t;
}
}
for(i=0;i<n;i++){//计算总长
sum+=a[i];
}
// printf("sum=%lld\n",sum);
for(i=x-1;i<y-1;i++){//计算从x到y的距离(递增)
sum1+=a[i];
}
sum2=sum-sum1;//计算反向距离
// printf("sum1=%lld\n",sum1);
// printf("sum2=%lld\n",sum2);
sum1=sum1*(y-x);
sum2=sum2*(n-y+x);
if(sum1<sum2){
printf("%lld\n",sum1);
}else{
printf("%lld\n",sum2);
}
return 0;
}
结果展示:
若存在不妥之处欢迎各位小伙伴指正~