0
点赞
收藏
分享

微信扫一扫

D. Zigzags (枚举+思维+统计) Educational Codeforces Round 94 (Rated for Div. 2)

原题链接: ​​https://codeforces.com/contest/1400/problem/D​​​D. Zigzags (枚举+思维+统计)  Educational Codeforces Round 94 (Rated for Div. 2)_算法
测试样例:

input
2
5
2 2 2 2 2
6
1 3 3 1 2 3
output
5
2

Note:

In the first test case, for any four indicesD. Zigzags (枚举+思维+统计)  Educational Codeforces Round 94 (Rated for Div. 2)_算法_02are valid, so the answer is the number of tuples.

In the second test case, there are 2 valid tuples:
(1,2,4,6): a1=a4 and a2=a6;
(1,3,4,6): a1=a4 and a3=a6.

题意: 给你一个整数序列。计算规定四元组格式的数量。

解题思路: 这道题是一道非常好的题,看似简单却难以下手,解决方法十分巧妙,OK,我们开始来解决这道题。此题十分直观,我们要计算四元组的数量,可四元组的下标是有四个的,都是未知的,我们只知道D. Zigzags (枚举+思维+统计)  Educational Codeforces Round 94 (Rated for Div. 2)_算法_03,如果暴力枚举显然不可能。我们发现这道题并不用在乎元素的大小关系,我们只在乎元素的出现次数,这也代表了它组成四元组的方案数,那么我们可以确定一个元素的下标,这里我们确定第三个 (最好确定中间,确定第二个也行,视情况而定,不同取法遍历顺序不同。由于确定实际上是不确定的,这自然是要枚举) ,那么确定完第三个编号后我们接下来就要去寻找其他三个的关系了。我们没有必要去真正的找下标,我们只要统计第四个编号的出现次数,这就是可以组合的方案数,再从第三个编号往前寻找和第三个编号值相同的,这个即为第一个编号。那么第二个编号呢?我们在往回遍历的途中当然也要统计,这里并不是统计出现次数了,而是直接统计方案数。(仔细理解,我可能表达的不是很好) 要注意的一点,在每次枚举确定的第三个编号时都要重置统计元素出现次数的数组,每次统计元素次数都要统计第三个编号之后的。 统计完了也相当于我们找到了第四个编号。OK,具体看代码,已贴详细注释。

AC代码:

/*
*
*
*/
#include<bits/stdc++.h> //POJ不支持

#define rep(i,a,n) for (int i=a;i<=n;i++)//i为循环变量,a为初始值,n为界限值,递增
#define per(i,a,n) for (int i=a;i>=n;i--)//i为循环变量, a为初始值,n为界限值,递减。
#define pb push_back
#define IOS ios::sync_with_stdio(false);cin.tie(0); cout.tie(0)
#define fi first
#define se second
#define mp make_pair

using namespace std;

const int inf = 0x3f3f3f3f;//无穷大
const int maxn = 1e5;//最大值。
typedef long long ll;
typedef long double ld;
typedef pair<ll, ll> pll;
typedef pair<int, int> pii;
//*******************************分割线,以上为自定义代码模板***************************************//

int t,n,a[maxn],cnt[maxn];//cnt用作计数,统计每个元素出现的次数。
void solve(){
ll ans=0,sum;//统计所有次数。
rep(i,1,n){
//我们确定第三个编号,统计第四个编号出现的次数。
sum=0;
memset(cnt,0,sizeof(cnt));//初始化。
rep(j,i+1,n)cnt[a[j]]++;//统计第三个编号之后每个元素出现次数
per(j,i-1,1){
if(a[j]==a[i]){
//说明找到第一个编号,我们统计之间有多少的方案数。
ans+=sum;
}
sum+=cnt[a[j]];//统计第二个编号的方案数。
}
}
cout<<ans<<endl;
}
int main(){
//freopen("in.txt", "r", stdin);//提交的时候要注释掉
IOS;
while(cin>>t){
while(t--){
cin>>n;
rep(i,1,n)cin>>a[i];
solve();
}
}
return 0;
}


举报

相关推荐

0 条评论