D. Coprime(掐时间复杂度点,思维题,贪心)

题目:

 

输入
6
3
3 2 1
7
1 3 5 2 4 7 7
5
1 2 3 4 5
3
2 2 4
6
5 4 3 15 12 16
5
1 2 2 3 6

输出
6
12
9
-1
10
7

思路:

        这是一道思维题,也有贪心,暴力枚举,在这里是掐着时间复杂度的思维题。

题目意思是 从数组中 找出互质的两个数 它们的下标最大。

所以我们可以在输入的时候标记一下对应元素的下标,然后是顺着标记,这样也是贪心,当出现相同的元素,我们取最大的下标覆盖之前标记的最小下标

又因为 这里元素数据范围是 1000 即(10^3)这里我们再进行两层循环 时间复杂度是 10^6 加上我们的 __gcd ()时间复杂度O(log min(a,b)),最坏情况nlog min(a,b),测试样例 1 <= T <= 10 数据范围 ,我们用 unordered_map 时间复杂度是 O(1),最坏的情况也是 O(n) 这里的 n 是我们的元素数据范围 1000

  整个循环过程,时间复杂度就是10^7 + 1000 + nlog min(a,b)——10^8 + 1000 + nlog min(a,b)之间

没有超过 10^9 所以不会超时,一般来说 超过 10^9 就会超时的

代码详解如下:

#include <iostream>
#include <unordered_map>
#include <algorithm>
#define endl '\n'
#define umap unordered_map
#define ___G std::ios::sync_with_stdio(false),cin.tie(0), cout.tie(0)
using namespace std;

inline void solve()
{

	umap<int, int>r;
	// r 用来标记元素对应的下标
	// 用 unordered_map 效率为 O(1)
	int n = 0;
	int ans = -1;
	cin >> n;
	for (int i = 1, x; i <= n; ++i)
	{
		cin >> x;
		// 标记好下标
		r[x] = i;
	}
	// 因为我们元素的数据范围为 1000 所以直接暴力两层循环
	// 查找我们下标和最大即可  这里的两层循环 效率为 O(n^2)  所以 O(1000 * 1000 == 1e6)
	// 这样是不会超时的,反而如果 用 我们定义的 n  则 O((2 * 1e5) * (2 * 1e5) == 4 * 1e10)就会超时了
	// 再加上 __gcd() 时间复杂度是 O(log min(a,b)) 可以刚刚恰着TLE分界线,差一丢丢就会超时的
	// 这是贪心思维题

	for (int i = 1; i <= 1000; ++i)
	{
		for (int j = 1; j <= 1000; ++j)
		{
			if (__gcd(i, j) == 1 && r[i] && r[j])
			{
				ans = max(ans, r[i] + r[j]);
			}
		}
	}
	cout << ans << endl;
}

int main()
{
	___G;
	int _t;
	cin >> _t;
	while (_t--)
	{
		solve();
	}

	return 0;
}

最后提交:

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值