# 简单模拟 介绍

PAT甲乙级中入门模拟题，入门模拟题又分为简单模拟，查找元素



## 何为模拟题？

模拟题是一类“题目怎么说，你就怎么做的”的题目



# 本次讲述两道稍微拔高的模拟题

The task is really simple: given N exits on a highway which forms a simple cycle
you are supposed to tell the shortest distance between any pair of exits.


Each input file contains one test case. For each case, the first line contains
an integer N (in [3, 105]), followed by N integer distances D1 D2 ... DN, where
Di is the distance between the i-th and the (i+1)-st exits, and DN is between
the N-th and the 1st exits. All the numbers in a line are separated by a space.
The second line gives a positive integer M (<=104), with M lines follow, each
contains a pair of exit numbers, provided that the exits are numbered from
1 to N. It is guaranteed that the total round trip distance is no more than 107.


For each test case, print your results in M lines, each contains the shortest
distance between the corresponding given pair of exits.


5 1 2 4 14 9
3
1 3
2 5
4 1


3
10
7


d1表示1出口到2出口的距离， 。。。。。。。dn表示n出口到1出口的距离，大体知道是一个环

#include <iostream>
using namespace std;
int s[100000];
int main()
{
int N, M;
cin >> N;
int temp;
int sum = 0;
for (int i = 1; i <= N; i++)//为了更清楚我选择从1开始存储，更加清晰明了
{
cin >> temp;
s[i] = temp;
}
cin >> M;
int a, b;
for (int j = 0; j < M; j++) {
int sum1 = 0, sum2 = 0;
cin >> a >> b;
if (a == b) cout << 0 << endl;
if (a > b) {//例如 5 2 ，我先计算 2 ~5 之间的距离，再计算 5 ~ 2的距离

for (int k = b; k < a; k++)
sum1 += s[k];

for (int k = a; ;) {
sum1 += s[k];
k++;
if (k > N) k = 1;
if (k == b) break;
}
}
if ( a < b ) {
for (int k = a; k < b; k++)
sum1 += s[k];
for (int k = b; ;) {
sum2 += s[k];
k++;
if (k > N) k = 1;
if (k == a) break;
}
}
cout << (sum1 > sum2 ? sum2 : sum1) << endl;//然后输出最小值
}
return 0;

}//其实代码逻辑完全符合题意，且编译通过！最后oj给出的答案是超时！！！


1. 发现这是一个循环.我们可以计算一边的距离，接着用总距离减一边的距离等于另一边的距离。
2. 接着又发现在 ·1 ·~ 5中，如果测试用例输入的是 1 2，那么肯定先计算 1 ->2边的距离后用总距离将其相减得 2 -> 1边的距离。
3. 但是如果输入的是1 4呢？ 那么肯定先计算 4 -> 1边的距离并用总距离将其相减得1 -> 4的距离
4. 总之计算短一边的距离

#include <iostream>
using namespace std;
int s[100000];
int main()
{
int N, M;
cin >> N;
int temp;
int sum = 0;
for (int i = 1; i <= N; i++)
{
cin >> temp;
s[i] = temp;
sum += temp;//sum来的到总环距离
}
cin >> M;
int a, b;
for (int j = 0; j < M; j++) {
int sum1 = 0, sum2 = 0;
cin >> a >> b;
if (a == b) cout << 0 << endl;
if (a > b) {
int t = a;
a = b;
b = t;
}
if ((b - a) <= (N/2))//判断计算哪边的距离更少
{
for (int k = a; k < b; k++)
sum1 += s[k];
}
else
{
for (int k = b; ;) {
sum1 += s[k];
k++;
if (k > N) k = 1;
if (k == a) break;
}
}
sum2 = sum - sum1;

cout << (sum1 > sum2 ? sum2 : sum1) << endl;//最后输出最短距离
}
return 0;
}


(注明：该代码在PAT里提交未显示超时，在Code Up显示超时.可能不同oj不一样吧，但在该题上Code up蛮严谨的)

## 可以的

#include <iostream>
using namespace std;
const int MAX = 100005;
int s[MAX];
int dis[MAX];
int main()
{
int N, M;
cin >> N;
int temp;
int sum = 0;
dis[0] = 0;//这里使dis[0]，left==1的情况会使用
for (int i = 1; i <= N; i++)
{
cin >> temp;
sum += temp;
dis[i] = sum;//记录从1位置到  i 位置的距离
}
cin >> M;
int left, right;
for (int j = 0; j < M; j++) {
cin >> left >> right;
if (left == right) cout << 0 << endl;
if (left > right) {//始终保持left<right
int t = left;
left = right;
right = t;
}
int sum1 = dis[right - 1] - dis[left - 1];
//两段的距离直接相减即可，大大降低时间复杂度
int sum2 = sum - sum1;
cout << (sum1 > sum2 ? sum2 : sum1) << endl;
}
return 0;
}


02-28 956
10-31 2633

08-19 987
07-27 2758
03-12 1830
09-06 5751
01-21 1万+
04-07 8万+