[暑假集训]Day5 T1 羊圈

时间限制: 1 Sec  内存限制: 512 MB
题目描述
ZYC的农场有N(1<=N<=100,000)块连续的区域排成一排,每块区域上都有确定数量的羊(每块区域不超过2000千只)。 
现在ZYC想要将一些区域用围墙围起来,作为信息社的优秀成员,当然要给自己出点难题:他希望围起来的区域里羊的总数/区域数的值最大,并且保证围起来的区域数不小于M。 
输入
第一行包括两个整数,分别表示N和M 
以下N行每行一个正整数,表示对应区域羊的数量(单位千只) 
输出
输出最大平均数(单位只) 
样例输入
10 6
6 
4
2
10
3
8
5
9
4
1
样例输出
6500

看到这道题时,我的第一个想法是打个前缀和暴力求解。于是第一份代码就出炉了。
 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 int n,k;
 4 long long a[100005],sum[100005],ans;
 5 int main()
 6 {
 7     scanf("%d%d",&n,&k);
 8     for(int i=1;i<=n;i++)
 9     {
10         scanf("%lld",&a[i]);
11         a[i]*=1000;
12     } 
13     for(int i=1;i<=k;i++) sum[1]+=a[i];
14     for(int i=2;i<=n-k+1;i++) 
15     {
16         sum[i]=sum[i-1]-a[i-1]+a[i+k-1];
17     }
18     for(int i=1;i<=n-k+1;i++)
19     {
20         ans=max(ans,sum[i]/k);
21         for(int j=i+k;j<=n;j++) 
22         {
23             sum[i]+=a[j];
24             ans=max(ans,sum[i]/(j-i+1));
25         }
26     }
27     printf("%lld",ans);
28     return 0;
29 }

然而在看到了100,000的数据范围后,我就知道这种做法会T,没想到还拿了71分。数据太水了。于是我就想到了二分。其实根本就没想到。

因为前缀和具有单调性,所以我们只需要求出平均值,然后用原数列减去平均值,最后找出一个非负子序列就可以了。(题解上好像是这么说的)

下面上参考代码:

 

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 int n,m;
 4 double a[100005],b[100005],sum[100005];
 5 int main()
 6 {
 7     scanf("%d%d",&n,&m);
 8     for(int i=1;i<=n;i++) scanf("%lf",&a[i]);//long long好像比double慢 
 9     double l=-1e6,r=1e6,flag=1e-8;
10     while(r-l>flag)
11     {
12         double mid=(l+r)/2;
13         for(int i=1;i<=n;i++) b[i]=a[i]-mid;//平均值减去原数列 
14         for(int i=1;i<=n;i++) sum[i]=sum[i-1]+b[i];//求一下前缀和 
15         double ans=-1e8,minn=1e8;
16         for(int i=m;i<=n;i++)
17         {
18             minn=min(minn,sum[i-m]);//不断更新左侧最小值 
19             ans=max(ans,sum[i]-minn);//找非负子序列 
20         }
21         if(ans>0) l=mid;
22         else r=mid;
23     }
24     printf("%d",int(r*1000));//按照题目要求输出 
25     return 0;
26 }

 

 

 

 

转载于:https://www.cnblogs.com/jiuduSHENBENG/p/11175737.html

这是一个比较复杂的项目,需要一些硬件和软件方面的知识。下面是一个简单的方案和代码实现: 硬件实现: 1. 传感器:使用温湿度传感器和液位传感器来检测羊圈内的温度、湿度、草料和水的水位。 2. 电机:使用步进电机控制喂草和喝水的装置,使用直流电机控制清洗装置。 3. 控制器:使用STM32单片机作为控制器,将传感器和电机连接到单片机上。 软件实现: 1. 读取传感器数据:使用单片机的ADC模块读取温湿度传感器和液位传感器的模拟信号,并进行数字转换。 2. 控制电机:使用单片机的PWM模块产生电机控制信号,控制喂草、喝水和清洗装置的运动。 3. 状态监测:根据传感器数据来监测羊圈内的状态,例如草料和水的水位、温湿度等。 4. 控制逻辑:根据状态监测来控制电机的运动,例如当草料和水的水位低于一定程度时,自动补充草料和水。 代码实现: 以下是一个简单的代码实现,仅供参考: ``` #include "stm32f10x.h" // 定义电机控制引脚 #define MOTOR_PIN GPIO_Pin_0 #define MOTOR_PORT GPIOA // 定义传感器引脚和通道 #define TEMP_PIN GPIO_Pin_1 #define TEMP_PORT GPIOA #define TEMP_CHANNEL ADC_Channel_1 #define HUMIDITY_PIN GPIO_Pin_2 #define HUMIDITY_PORT GPIOA #define HUMIDITY_CHANNEL ADC_Channel_2 #define WATER_PIN GPIO_Pin_3 #define WATER_PORT GPIOA #define WATER_CHANNEL ADC_Channel_3 // 定义电机控制周期 #define MOTOR_PERIOD 10000 // 初始化ADC模块 void ADC_Init(void) { ADC_InitTypeDef ADC_InitStruct; GPIO_InitTypeDef GPIO_InitStruct; RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1 | RCC_APB2Periph_GPIOA, ENABLE); // 配置温度传感器引脚 GPIO_InitStruct.GPIO_Pin = TEMP_PIN; GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AIN; GPIO_Init(TEMP_PORT, &GPIO_InitStruct); // 配置湿度传感器引脚 GPIO_InitStruct.GPIO_Pin = HUMIDITY_PIN; GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AIN; GPIO_Init(HUMIDITY_PORT, &GPIO_InitStruct); // 配置水位传感器引脚 GPIO_InitStruct.GPIO_Pin = WATER_PIN; GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AIN; GPIO_Init(WATER_PORT, &GPIO_InitStruct); ADC_InitStruct.ADC_Mode = ADC_Mode_Independent; ADC_InitStruct.ADC_ScanConvMode = DISABLE; ADC_InitStruct.ADC_ContinuousConvMode = DISABLE; ADC_InitStruct.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None; ADC_InitStruct.ADC_DataAlign = ADC_DataAlign_Right; ADC_InitStruct.ADC_NbrOfChannel = 3; ADC_Init(ADC1, &ADC_InitStruct); // 配置ADC通道 ADC_RegularChannelConfig(ADC1, TEMP_CHANNEL, 1, ADC_SampleTime_239Cycles5); ADC_RegularChannelConfig(ADC1, HUMIDITY_CHANNEL, 2, ADC_SampleTime_239Cycles5); ADC_RegularChannelConfig(ADC1, WATER_CHANNEL, 3, ADC_SampleTime_239Cycles5); ADC_Cmd(ADC1, ENABLE); } // 读取温度值 float GetTemperature(void) { ADC_SoftwareStartConvCmd(ADC1, ENABLE); while (ADC_GetFlagStatus(ADC1, ADC_FLAG_EOC) == RESET); uint16_t adc_value = ADC_GetConversionValue(ADC1); float voltage = adc_value * 3.3 / 4096; float temperature = (voltage - 0.76) / 0.0025 + 25; return temperature; } // 读取湿度值 float GetHumidity(void) { ADC_SoftwareStartConvCmd(ADC1, ENABLE); while (ADC_GetFlagStatus(ADC1, ADC_FLAG_EOC) == RESET); uint16_t adc_value = ADC_GetConversionValue(ADC1); float voltage = adc_value * 3.3 / 4096; float humidity = (voltage - 0.1515) / 0.00636; return humidity; } // 读取水位值 float GetWaterLevel(void) { ADC_SoftwareStartConvCmd(ADC1, ENABLE); while (ADC_GetFlagStatus(ADC1, ADC_FLAG_EOC) == RESET); uint16_t adc_value = ADC_GetConversionValue(ADC1); float voltage = adc_value * 3.3 / 4096; float water_level = voltage / 3.3 * 100; return water_level; } // 控制电机 void ControlMotor(uint16_t duty_cycle) { TIM_OCInitTypeDef TIM_OC_InitStruct; RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE); GPIO_InitTypeDef GPIO_InitStruct; GPIO_InitStruct.GPIO_Pin = MOTOR_PIN; GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF_PP; GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(MOTOR_PORT, &GPIO_InitStruct); TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStruct; TIM_TimeBaseInitStruct.TIM_Prescaler = 72 - 1; TIM_TimeBaseInitStruct.TIM_Period = MOTOR_PERIOD - 1; TIM_TimeBaseInitStruct.TIM_ClockDivision = TIM_CKD_DIV1; TIM_TimeBaseInitStruct.TIM_CounterMode = TIM_CounterMode_Up; TIM_TimeBaseInit(TIM2, &TIM_TimeBaseInitStruct); TIM_OC_InitStruct.TIM_OCMode = TIM_OCMode_PWM1; TIM_OC_InitStruct.TIM_OutputState = TIM_OutputState_Enable; TIM_OC_InitStruct.TIM_Pulse = duty_cycle; TIM_OC_InitStruct.TIM_OCPolarity = TIM_OCPolarity_High; TIM_OC1Init(TIM2, &TIM_OC_InitStruct); TIM_Cmd(TIM2, ENABLE); } int main(void) { ADC_Init(); while (1) { float temperature = GetTemperature(); float humidity = GetHumidity(); float water_level = GetWaterLevel(); if (temperature > 25 && humidity > 50 && water_level < 50) { ControlMotor(8000); // 喂草 } else if (temperature > 25 && humidity < 50 && water_level < 50) { ControlMotor(4000); // 喝水 } else if (temperature < 25 && humidity < 50 && water_level < 50) { ControlMotor(12000); // 清洗 } } } ``` 以上代码仅供参考,实际实现中需要根据具体的硬件和实际需求进行调整。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值