基本思想:
对于这个环形的正权值队列来说,完全可以从第一个节点计数,用1~i和1~j节点的距离来计算i~j节点的距离;
注意点:
1.对于高次个数,遍历不靠谱,找机会打表和优化结构;
2.对于正负权值要注意;
超时代码:
1 #include<iostream> 2 #include<stdlib.h> 3 #include<stdio.h> 4 #include<vector> 5 #include<string> 6 #include<math.h> 7 #include<algorithm> 8 using namespace std; 9 using std::vector; 10 const int maxn = 100009; 11 int dis[maxn]; 12 int main() { 13 int n; 14 scanf("%d", &n); 15 for (int i = 0; i < n; i++) 16 scanf("%d", &dis[i]); 17 int m; 18 scanf("%d", &m); 19 for (int i = 0; i < m; i++) { 20 int a, b; 21 scanf("%d %d", &a, &b); 22 a--; 23 b--; 24 int d1=0,d2=0; 25 int in = a; 26 while (in != b) { 27 d1 += dis[in]; 28 in = (in + 1) % n; 29 } 30 in = a; 31 while (in != b&&d2<d1) { 32 in = ((in - 1) + n) % n; 33 d2 += dis[in]; 34 } 35 printf("%d\n", min(d1, d2)); 36 } 37 system("pause"); 38 return 0; 39 }
预处理代码:
1 #include<iostream> 2 #include<stdlib.h> 3 #include<stdio.h> 4 #include<vector> 5 #include<string> 6 #include<math.h> 7 #include<algorithm> 8 using namespace std; 9 using std::vector; 10 const int maxn = 100009; 11 int dis[maxn] = {0}; 12 int dis_pre[maxn]; 13 int main() { 14 int n; 15 int sum = 0; 16 scanf("%d", &n); 17 for (int i = 1; i <= n; i++) { 18 scanf("%d", &dis[i]); 19 dis_pre[i+1] = dis[i] + dis_pre[i]; 20 sum += dis[i]; 21 } 22 int m; 23 scanf("%d", &m); 24 for (int i = 0; i < m; i++) { 25 int a, b; 26 scanf("%d %d", &a, &b); 27 int d = abs(dis_pre[b] - dis_pre[a]); 28 printf("%d\n", min(d,sum-d)); 29 } 30 system("pause"); 31 return 0; 32 }
原文地址:https://www.cnblogs.com/songlinxuan/p/12187458.html
时间: 2024-11-08 19:16:32