AcWing 3347. 菊花链

18 篇文章 0 订阅
17 篇文章 0 订阅
该博客介绍了如何利用C++和Java编程解决一个算法问题,即在给定一系列花朵及其花瓣数的情况下,找出包含平均花瓣数的照片数量。博主详细阐述了题目的数据范围和限制,提出了解题思路,即通过两重循环枚举拍照区间,并使用集合存储区间内的花瓣数,检查是否存在平均值。随后提供了完整的C++和Java代码实现,实现了从头到尾的解决方案。
摘要由CSDN通过智能技术生成

题目

每天,作为她绕农场行走的一部分,奶牛 Bessie 会经过她最喜爱的草地,其中种有 N 朵花(五颜六色的雏菊),编号为 1…N,排列成一行。

花 i 有 pi 朵花瓣。

作为一名崭露头角的摄影家,Bessie 决定给这些花拍些照片。

具体地说,对于每一对满足 1 ≤ i ≤ j ≤ N 的花 (i,j),Bessie 会给从花 i 到花 j 之间的所有花(包括 i 和 j)拍一张照。

后来 Bessie 查看这些照片时注意到有些照片里存在「平均」的花——一朵恰好有 P 朵花瓣的花,其中 P 等于照片中所有花的花瓣数量的平均值。

Bessie 的照片中有几张存在平均的花?

输入格式
输入的第一行包含 N。

第二行包含 N 个空格分隔的整数 p1…pN

输出格式
输出存在平均的花的照片数量。

数据范围
1 ≤ N ≤ 100,
1 ≤ pi ≤ 1000

输入样例:

4
1 1 2 3

输出样例:

6

样例解释
每张仅包含一朵花的照片均会被计入答案(在这个样例中有 4 张)。

另外,在这个样例中 (i,j) 为 (1,2) 和 (2,4) 所对应的照片也存在平均的花。

解题思路

首先,该题的数据范围为 1 ≤ N ≤ 100,可见数据量很小,允许 O(n3) 的算法,(最坏情况下100 * 100 * 100 = 106 < 108),所以这题可以直接暴力枚举;

所以,我们只需要两重循环,来枚举拍照区间 [i, j],同时用 Set 记录区间 [i, j] 内出现的花瓣数,并求得区间 [i, j] 之间的花瓣数的平均值,判断该平均值是否在区间 [i, j] 内出现过即可;

由于每张仅包含一朵花的照片均会被计入答案,所以 i == j 的情况可以直接跳过,存在平均的花的照片数量至少为 N,之后每有一个符合条件则在此基础上加一即可。

AC代码

C++

#include<iostream>
#include<algorithm>
#include<set>

using namespace std;

const int N = 101;
int p[N];

int main()
{
    int n = 0;
    scanf("%d", &n);

    for(int i = 0; i < n; i++) scanf("%d", &p[i]);

    int res = n;
    for(int i = 0; i < n - 1; i++)
    {
        double sum = p[i];
        set<double> s;
        s.insert(p[i]);
        for(int j = i + 1; j < n; j++)
        {
            sum += p[j];
            s.insert(p[j]);
            if(s.count(sum / (j - i + 1))) res++;   // 判断照片中是否有花瓣数等于照片中花瓣数的平均值
        }
    }

    printf("%d", res);
}

Java

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.util.HashSet;
import java.util.Set;

public class Main {
	
	public static void main(String[] args) throws IOException {
		BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
		PrintWriter out = new PrintWriter(System.out);
		
		int n = Integer.parseInt(in.readLine());
		int[] p = new int[n];
		
		String string = in.readLine();
		
		for(int i = 0; i < n; i++) p[i] = Integer.parseInt(string.split(" ")[i]);
		
		int count = n;
		for(int i = 0; i < n - 1; i++) {
			double sum = p[i];
			
			Set<Double> set = new HashSet<Double>();
			set.add((double)p[i]);
			
			for(int j = i + 1; j < n; j++) {
				set.add((double)p[j]);
				sum += p[j];
				if(set.contains(sum / (j - i + 1))) count++;	// 判断照片中是否有花瓣数等于照片中花瓣数的平均值
			}
		}
		
		out.print(count);
		out.flush();
		in.close();
	}

}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值