洛谷P1109 学生分组
题目描述
有 n 组学生,给出初始时每组中的学生个数,再给出每组学生人数的上界 R 和下界 L (L≤R),每次你可以在某组中选出一个学生把他安排到另外一组中,问最少要多少次才可以使 N 组学生的人数都在 [L,R] 中。
输入格式
第一行一个整数 n,表示学生组数;
第二行 n 个整数,表示每组的学生个数;
第三行两个整数 L,R,表示下界和上界。
输出格式
一个数,表示最少的交换次数,如果不能满足题目条件输出 −1−1。
输入输出样例
输入 #1复制
2 10 20 10 15
输出 #1复制
5
说明/提示
数据范围及约定
对于全部数据,保证 1≤n≤50。
题目分析
1,贪心策略,进行模拟,首先判断是否能满足题目条件,满足题目条件的根本原因是输入n个数的总和必须满足在n组l和r的区间,所以就演变成了sum>l*n&&sum<r*n;
2,满足题目条件后,根据题目,分别统计超出右界和左界,因为右界的值是可以填补左界的,所以统计最大的值
代码示例
#include<bits/stdc++.h>
using namespace std;
int a[51],l,r,sum=0;
int main(){int n,k=0,m=0;cin>>n;for(int i=0;i<n;i++){cin>>a[i];sum+=a[i];//总和}cin>>l>>r;if(sum<l*n||sum>r*n){cout<<-1;return 0;}//判断是否符合题目条件for(int i=0;i<n;i++){if(a[i]>r)k+=a[i]-r;//超出右界if(a[i]<l)m+=l-a[i];//超出左界}printf("%d",k>m?k:m);}
洛谷P2708 硬币翻转
题目描述
有很多个硬币摆在一行,有正面朝上的,也有背面朝上的。正面朝上的用 1 表示,背面朝上的用 0 表示。
现在要求从这行的第一个硬币开始,将从第一个硬币开始的前若干个硬币同时翻面,求如果要将所有硬币翻到正面朝上,最少要进行这样的操作多少次?
输入格式
一个字符串,由 0 和 1 组成,表示硬币的初始状态。
输出格式
一个整数,表示要翻转的最少次数。
输入输出样例
输入 #1复制
10
输出 #1复制
2
说明/提示
样例解释
- 第 1次翻转:把第一个硬币翻到反面,字符串为 00;
- 第 2 次翻转:把第一、二个硬币一起翻到正面,字符串为 11,翻转完成,输出 2。
数据范围
记 �n 表示硬币的总个数,
- 对于 20%20% 的数据,1≤n≤10;
- 对于 50%50% 的数据,1≤n≤104;
- 对于 100%100% 的数据,1≤n≤106。
题目分析
1,运用模拟可以得出一直如果当前的值与下一个不一样,则次数肯定要加一(翻转),最后会得到一个全是1或者全是0
2.判断最后一个字符,如果是0,就再翻转一次,是1的话直接输出
3,注意,这里的翻转,是将1到i全翻转一次
代码示例
#include<iostream>
#include<cstdio>
using namespace std;
int main()
{string s;cin>>s;int sum=0;int len=s.length();for(int i=0;i<len-1;i++)//一直比较{if(s[i]!=s[i+1])sum++;}if(s[len-1]=='0')//判断加一sum++;cout<<sum;
}