题目:
果老师找到了很多不同颜色的珠子,他把这些珠子排成了一列,每个珠子的颜色用1,2···表示.定义一个区间的美观度为区间中不同颜色的珠子个数现在果老师想知道,在所有个n×(n+1)/2区间中,所有区间的美观度之和是多少.
输出格式
输出一个整数,表示所有区间的美观度之和
样例输入
6
1 2 2 3 3 1
样例输出
39
本题依旧是区间和,但可以用两种方法:
FF1:
假设下标从1开始,那么从1到3的不同颜色珠子的个数是以从1到2的不同颜色珠子的个数为基础的。我们可以利用一个标记数组,来找出一行的不同珠子的情况,并存放在dp数组中,dp数组的含义就是当前的位置i到位置j的长度的不同珠子的个数。
FF2 :
区间的数量显然是组合数,那么我们可以两层for循 环,第一层for循环枚举左端点,第二层for循环枚举右端点,我们依次遍历下去,如果当前区间这个数是第一次出现,也就是说第一次出现该颜色,那么我们就计数加一,并且标记该颜色就可以了
FF1代码同学们可以试着写下
FF2代码如下:
#include <bits/stdc++.h>
using namespace std;
const int maxn = 1e5 + 10;
int a[maxn], sum[maxn];
int main()
{
int n;
while (~scanf("%d", &n))
{
int cnt = 0;
for (int i = 1; i <= n; ++i)
scanf("%d", &a[i]);
for (int i = 1; i <= n; ++i)
{
int ans = 0;
memset(sum, 0, sizeof(sum));
for (int j = i; j <= n; ++j)
{
if (sum[a[j]] == 0)
ans++;
sum[a[j]]++;
cnt += ans;
}
}
printf("%d\n", cnt);
}
}
拓展:
set 翻译为集合,是一个内部自动有序且不含重复元素的容器。当出现需要去掉重复元素的情况,而且有可能因这些元素比较大或者类型不是 int 型而不能直接开散列表,在这种情况下就可以用 set 来保留元素本身而不考虑它的个数。
所以,我们还可以在写一种代码:
#include<iostream>
#include<set>
using namespace std;
int a[1001];
int sum[1001];
int main()
{
set<int>s;
int n;
scanf("%d",&n);
for(int i=0;i<n;i++)
scanf("%d",&a[i]);
int sum=0;
for(int j=0;j<n;j++)
{
for(int k=j;k<n;k++)
{
s.insert(a[k]);
sum+=s.size();
}
s.clear();
}
printf("%d\n",sum);
return 0;
}
希望能帮到你们,我们下个题解再见,Goodbye~~