原题链接:https://codeforces.ml/problemset/problem/1541/B
题目大意:给你一个长度为n的数组,让你在里面找出符合
的数组对有几对,且 i 一定小于 j ;
题解:首先想到的就是暴力两重循环把所有可行解找出来,看看数据范围10^5
简单暴力必超时;交了一发,果然(试试呗,万一系统抽了);
暴力不行,那就想着对条件下手,观察式子可以发现:
对应{ a[i] i};他的数对是固定的倍数,比如a[1]=3,那么与他成对的只可能是{a[2] 1} ,{ a[5] 6} { a[8] 9} (分别对应i+j=3,6,9),那就可以用一 次遍历找出对应倍数的下标,然后判断该下标对应的数是否满足条件;
代码:
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
ll num[100005] = { 0 };
int main()
{
int n;
cin >> n;
while (n--)
{
memset(num, 0, sizeof(num));
ll a;
cin >> a;
for (int i = 1; i <= a; i++)
{
cin >> num[i];
}
ll ans = 0;
for (int i = 1; i <= a; i++)
{
ll id;
ll cnt = 1;
while (true)
{
id = num[i] * cnt - i;//计算出对应下标
if (id > a)//保证在数组范围内
{
break;
}
if (!(i < id))//保证i<j,防止重复
{
cnt++;
continue;
}
if (num[id] * num[i] == i + id)//满足条件ans++且倍数加1
{
ans++;
cnt++;
}
else//不满足,只倍数+1
{
cnt++;
}
}
}
cout << ans << endl;
}
return 0;
}
ps:马上去学markdown(tao);