这道题,折磨了我一个多小时,前前后后写了三个算法。

1046 Shortest Distance (20 point(s))

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.

Input Specification:

Each input file contains one test case. For each case, the first line contains an integer N (in [3,10​5​​]), followed by N integer distances D​1​​D​2​​ ⋯ D​N​​, where D​i​​ is the distance between the i-th and the (i+1)-st exits, and D​N​​ 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 (≤10​4​​), 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 10​7​​.

Output Specification:

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

Sample Input:

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

Sample Output:

3
10
7

题目特很简单,就是一个多个点组成的环形,求两个点之间的最短距离。阳历第一行5代表5个点,后面第i个数代表第一个点到第i+1个点的距离。等等。。。

然后我第一个想法是循环链表,第一次完成的写链表的代码,废了九牛二虎之力,写了一个循环链表,然后就贼舒服的求最短距离。

先贴出来的我写的代码

#include<cstdio>
class Node
{
public:
int num;
int dis;
Node* next;
Node* pre;
}; class cycleLinkList
{
public:
cycleLinkList();
void insert_back(int num, int dis);
int find_nearest(int prenum,int lastnum);
//void displayAll(void);
private:
Node* head;
};
cycleLinkList::cycleLinkList()
{
head = new Node;
head->num = ;
head->pre = head;
head->next =
head;head->dis = ;
}
void cycleLinkList::insert_back(int num, int dis) {
Node* pre = head->next;
while (pre->next!=head)
{
pre = pre->next;
}
Node* new_Node=new Node;
new_Node->dis = dis;
new_Node->num = num;
new_Node->next = head;
new_Node->pre = pre;
pre->next->pre = new_Node;
pre->next = new_Node;
}
int cycleLinkList::find_nearest(int prenum, int lastnum) {
Node* pre = head->next;
while (pre->num != prenum)
{
pre = pre->next;
}
int predistance=,nextdistance=;
Node* pre_dir = pre;
while (pre_dir->num != lastnum)
{
pre_dir = pre_dir->pre;
predistance += pre_dir->dis; }
Node* next_dir = pre;
while (next_dir->num != lastnum)
{
nextdistance += next_dir->dis;
next_dir = next_dir->next;
}
if (nextdistance >= predistance)return predistance;
else return nextdistance; }
/*
void cycleLinkList::displayAll(void)
{
Node* _head = head->next;
while (_head != head)
{
printf("%d %d\n", _head->num, _head->dis);
_head = _head->next;
}
printf("pre\n");
_head = head->pre;
while (_head != head)
{
printf("%d %d\n", _head->num, _head->dis);
_head = _head->pre;
}
}*/ int main()
{
int n,m,dis;
scanf("%d", &n);
cycleLinkList data;
for (int i = ; i < n; i++){
scanf("%d", &dis);
data.insert_back(i + , dis);
}
//data.displayAll();
//printf("insert");
scanf("%d", &m);
for (int i = ; i < m; i++){
int pre_num, last_num;
scanf("%d%d", &pre_num,&last_num);
printf("%d\n",data.find_nearest(pre_num, last_num));
}
return ;
}

写完之后运行很正常,当然是很舒服啦,但是。。。提交给OJ就是运行超时,我也很无奈,循环链表那么直观,竟然不让用。

那我就用数组呗,第二个想法,用数组。

 #include<cstdio>
int main()
{
int dis[],n,m,total_dis=;
memset(dis, , (*sizeof(int)));
scanf("%d", &n);
for (int i = ; i < n; i++)
{
scanf("%d", &dis[i]);
total_dis += dis[i];
}
scanf("%d", &m);
for (int i = ; i < m; i++) {
int prenum, lastnum,nextdis=;
scanf("%d%d", &prenum, &lastnum);
if (prenum > lastnum) { int temp = prenum;prenum = lastnum;lastnum = temp; } for (int j = prenum - ;j < lastnum - ;j++)
nextdis += dis[j];
if (total_dis - nextdis >= nextdis) printf("%d\n", nextdis);
else printf("%d\n", total_dis-nextdis);
}
return ;
}

不过这个代码交上去,还是有一个运行超时。牛客PATOJ的全部通过,但PAT官网OJ最后一个超时。

主要原因出在我每次计算最短距离都要遍历数组,大概相当于O(m*n)的复杂度。运行时间太长。

然后我就求助教材了,发现可以给数组保存为第i个元素是第i个点到第i个点的距离,然后求两个点a,b之间的距离就可以直接dis[b]-dis[a]了。(其中a<b,否则交换)

这样的话就输入的时候遍历n次,找最短距离的时候遍历m次就行了。

 #include<cstdio>
#include<algorithm>
using namespace std;
int main()
{
int dis[], n, m, total_dis = ;
scanf("%d", &n);
for (int i = ; i < n; i++)
{
int temp;
scanf("%d", &temp);
dis[i] = total_dis;
total_dis += temp;
//printf("i: %d dis:%d total:%d\n", i, dis[i],total_dis);
}
scanf("%d", &m);
for (int i = ; i < m; i++) {
int prenum, lastnum;
scanf("%d%d", &prenum, &lastnum);
if (prenum > lastnum) swap(prenum, lastnum);
int temp = dis[lastnum-] - dis[prenum-];
printf("%d\n",min(temp,total_dis-temp));
}
return ;
}

然后终于通过啦。

这也学到了一点,拿到题先想想有没有简化的方法,按照最简单的思维去写代码,往往可能运行超时。

就像这道题最后一种方法,就简化了很多。越简单的题越需要脑子,不要一拿上来就做。

int main(){int dis[100005],n,m,total_dis=0;memset(dis, 0, (100005*sizeof(int)));scanf("%d", &n);for (int i = 0; i < n; i++){scanf("%d", &dis[i]);total_dis += dis[i];}scanf("%d", &m);for (int i = 0; i < m; i++) {int prenum, lastnum,nextdis=0;scanf("%d%d", &prenum, &lastnum);if (prenum > lastnum) { int temp = prenum;prenum = lastnum;lastnum = temp; }for (int j = prenum - 1;j < lastnum - 1;j++)nextdis += dis[j];if (total_dis - nextdis >= nextdis) printf("%d\n", nextdis);else printf("%d\n", total_dis-nextdis);}return 0;}

PAT——甲级1046S:shortest Distance的更多相关文章

  1. PAT 甲级 1046 Shortest Distance

    https://pintia.cn/problem-sets/994805342720868352/problems/994805435700199424 The task is really sim ...

  2. PAT 甲级 1046 Shortest Distance (20 分)(前缀和,想了一会儿)

    1046 Shortest Distance (20 分)   The task is really simple: given N exits on a highway which forms a ...

  3. PAT甲级——A1046 Shortest Distance

    The task is really simple: given N exits on a highway which forms a simple cycle, you are supposed t ...

  4. PAT甲 1046. Shortest Distance (20) 2016-09-09 23:17 22人阅读 评论(0) 收藏

    1046. Shortest Distance (20) 时间限制 100 ms 内存限制 65536 kB 代码长度限制 16000 B 判题程序 Standard 作者 CHEN, Yue The ...

  5. PAT Advanced 1046 Shortest Distance (20 分) (知识点:贪心算法)

    The task is really simple: given N exits on a highway which forms a simple cycle, you are supposed t ...

  6. PAT A1046 Shortest Distance

    PAT A1046 Shortest Distance 标签(空格分隔): PAT TIPS: 最后一个数据点可能会超时 #include <cstdio> #include <al ...

  7. PAT (Advanced Level) Practice 1046 Shortest Distance (20 分) 凌宸1642

    PAT (Advanced Level) Practice 1046 Shortest Distance (20 分) 凌宸1642 题目描述: The task is really simple: ...

  8. PAT 1046 Shortest Distance

    1046 Shortest Distance (20 分)   The task is really simple: given N exits on a highway which forms a ...

  9. PAT 1046 Shortest Distance[环形][比较]

    1046 Shortest Distance(20 分) The task is really simple: given N exits on a highway which forms a sim ...

随机推荐

  1. 2018.8.1 Java中的反射和同步详解

    为何要使用同步? java允许多线程并发控制,当多个线程同时操作一个可共享的资源变量时(如数据的增删改查), 将会导致数据不准确,相互之间产生冲突,因此加入同步锁以避免在该线程没有完成操作之前,被其他 ...

  2. caffe resize用interpolation

    opencv的resize默认的是使用双线性插值INTER_LINEAR,也可以是尝试其他的方式进行插值操作 if (param.random_interpolation_method()) { // ...

  3. asp .net core 中间件的简单 使用

    在startup 的cs文件中 2.捕获异常的中间件 可以在浏览器中 显示异常信息 在开发环境的境况下,该中间件会帮你 捕获异常

  4. Spring初始化Bean或销毁Bean前执行操作的方式

    如果想在Spring初始化后,或者销毁前做某些操作,常用的设定方式有三种: 第一种:通过 在xml中定义init-method 和 destory-method方法 推荐使用,缺陷是只能在XML中使用 ...

  5. 第一个AngularJS控制器

    <!DOCTYPE html><html><head><meta http-equiv="Content-Type" content=&q ...

  6. 3.Netty的粘包、拆包(二)

    Netty提供的TCP数据拆包.粘包解决方案 1.前言 关于TCP的数据拆包.粘包的介绍,我在上一篇文章里面已经有过介绍. 想要了解一下的,请点击这里 Chick Here! 今天我们要讲解的是Net ...

  7. Python——合集

    合集 主要功能是对比列表中的信息,进行关系测试. 特点:1. 去重,把一个列表变成合集,就自动去重了.2. 关系测试,测试两组数据之间的交集.差集.并集等关系.3. 没有插入功能,只能添加.4. 一个 ...

  8. Session的生命同期

    一.什么是Session,怎么用 Session是存放用户与web服务器之间的会话,即服务器为浏览器开辟的存储空间. 由于浏览器与服务器之间的会话是无状态(无状态的意思是会话之间无关联性,无法识别该用 ...

  9. IDEA的下载安装和激活

    1.下载网站http://www.jetbrains.com/ 2. 3. 4.注意要下载Ultimate版本 5.安装 下载完成后直接下一步,傻瓜式安装 6.激活,在图片位置输入激活码即可 !!!! ...

  10. 【jQuery】输入框自带清除按钮

    最近一个项目,需要在输入框时右边出现“X”标志,点击X即可清空,主要使用了click和blur事件,难点在于点击‘X’时,input框获得焦点时出现“X”标志,而点击"x"标志时i ...