【周赛题解:Acwing5465. 指针运动 】

本文描述了一个编程问题,涉及在一个环形数组中,指针按特定条件移动,目标是找出指针最终停止并指向的元素下标。文章给出了详细的大致思路和C++代码实现,强调了避免模拟方法以优化时间复杂度。
摘要由CSDN通过智能技术生成

很久没有写代码了,感觉很明显的脑子转不过来了,题意不难理解,但是需要比较细心的写代码,记录一下吧~~

1.题目

给定一个长度为 n 的非负整数环形数组 a1,a2,…,an
由于环形数组首尾相连,因此 an的下一位元素是 a1
有一个指针,指向该数组中的元素。初始时,该指针指向 a1
接下来执行以下循环操作(由伪代码表示):
while(指针指向的元素不等于 0)
{
令当前数组中所有大于 0 的元素减 1,并令指针指向下一位元素;
}
请你输出循环操作结束后,该指针指向的元素的下标。

输入格式
第一行包含整数 n
第二行包含 n个整数 a1,a2,…,an

输出格式
一个整数,表示指针最终指向的元素的下标。

2.大致思路

1.首先可以肯定的是,绝对不可以用模拟(数值过大时,例如1e9,绝对会超时间复杂度)
2.因此可以有以下思路:
(1)对于每一个下标为i的指针(指针的下标从1-n)有其数值d[i],在第一次指向i时,已经有i-1次-1,就是说在指向时d[i]=d[i]-(i-1),判断此时如果d[i]-(i-1)<=0,则最终指向的元素的下标为i,否则,我们对之后的情况继续模拟。
(2)在第一次指向i时(d[i]>0),在这个while循环(题目中给出的伪代码)中d[i]-1,假设之后的指针没有符合跳出while的情况,则在第二次到达指针i前,共有n次-1,就是说第二次到达指针i时d[i]=d[i]-(i-1)-n,由此可以类推,第k次到达指针i时d[i]=d[i]-(i-1)-(k-1)*n,如果此时d[i]<=0,则说明i为最终指向的元素下标
(3)但是,在这个过程中,我们如何保证i是第一个符合条件的元素呢?不难发现,我们只需要按照1-n顺序进行遍历即可,然后比较代码中的a[i](就是第几次可以跳出循环,a[i]越小就可以越早跳出去了~)
然后就开始快乐的写代码了~~

AC代码

#include<iostream>
#include<algorithm>
#include<cstring>
using namespace std;

const int N = 1e5 + 50;
int n,d[N],a[N];

int main() {
	cin >> n;
	int res = 0;
	int cnt = 1e9;
	for (int i = 0; i < n; i++) {
		cin >> d[i];
	}//0,n-1  1,n-1
	for (int i = 0; i < n; i++) {
		d[i] -= i;
		a[i]++;
		if (d[i] <= 0) {
			res = i + 1;
			break;
		}
		if(d[i]%n!=0)a[i]++;
		a[i] += d[i] / n;
		if (a[i] < cnt) {
			cnt = a[i];
			res = i + 1;
		}
		//printf("a[%d]=%d\n", i, a[i]);
	}
	printf("%d", res);
	return 0;
}
  • 3
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值