关键在于贪心策略的选择,也就是一个解决问题的思路
1.Team
题目来源,点击查看
题目分析:对于一道题,只要三个人中有两个及以上的人有思路,就能解决这道题目,那么对于给定的n道题目有几道可以做?
解题思路:判断题是否可做(有解题思路的人>=2),可做则数量+1;
代码示例:
#include <iostream>
using namespace std;
int main() {
int n;
cin>>n;
int a[3];
int sum;
int number=0; //解决问题的数量
for(int i=0;i<n;i++)
{
sum=0;
for(int i=0;i<3;i++)
{
cin>>a[i];
if(a[i]==1)
sum++;
}
if(sum>=2) //判断能否解决
number++;
}
cout<<number;
return 0;
}
2. Choosing Teams
题目来源,点击查看
题目分析:每个队员最多只能参加5次ACM ICPC,3人一队;给定每个队员参加过该比赛的次数,以及之后需要进行的比赛次数,判断至少能组成几个队伍进行>=k次比赛
解题思路:先判断符合条件的队员(还能比赛次数>=k),之后再看符合条件的人能组成几对
代码示例:
#include <iostream>
using namespace std;
int main() {
int n,k;
int y[2005];
cin>>n>>k;
int sum=0; //符合要求的组队成员
for(int i=0;i<n;i++)
{
cin>>y[i];
if(y[i]<=(5-k))
sum++;
}
cout<<sum/3<<endl;
return 0;
}
3.Feed the cat
题目来源,点击查看
题目分析:需要计算出喂猫的最小花费
解题思路:分为两种情况,一是在8点前醒来,二是在8点或8点后醒来;第一种情况下有直接买和等到8点买两种选择。分别计算在两种情况下的花费,之后找出最小值
代码示例:
#include <iostream>
#include <iomanip> //精度头文件
#include <algorithm>//max min
#include <cmath> //向上取整
using namespace std;
int main() {
float hh,mm;
float h,d,c,n;
cin>>hh>>mm;
cin>>h>>d>>c>>n;
float nowMoney=1e9;
float eightMoney=1e9;
float afterMoney=1e9;
float time=hh*60+mm;
//在8点前醒来
if(time<1200)
{
//醒过来直接购买
nowMoney=ceil(h/n)*c; //直接买的钱=需要的面包数量*面包价格
//等到8点再去买8折的猫粮
float eh= ((20-hh)*60-mm)*d+h; //8点的饥饿值
eightMoney= ceil(eh/n)*c*0.8; //8点后买的钱=需要的面包数*八折面包
}
//在8点或者8点后醒来买8折猫粮
else if(time>=1200)
{
afterMoney= ceil(h/n)*c*0.8;
}
float temp=min(nowMoney,eightMoney);
float minMoney=min(temp,afterMoney);
cout<<fixed<<setprecision(4)<<minMoney;
return 0;
}
4.Even Array理想数组偶数阵列
题目来源,点击查看
题目分析:需要把一个数组变为理想数组(a[i]%2 = i%2),求出所需最小操作数
解题思路:首先找出需要交换的个数,计算奇数位不符合条件的个数odd,偶数位不符合条件的个数even;再判断,如果odd=even,那么表示可以交换,交换个数为odd(even)的个数,若不相等,那么输出-1;
代码示例:
#include <iostream>
using namespace std;
int main() {
int t,n;
int a[45];
cin>>t;
for(int i=0;i<t;i++)
{
cin>>n;
int odd=0; //奇数位错误个数
int even=0; //偶数位数错误个数
//1.计算
for(int i=0;i<n;i++)
{
cin>>a[i];
//计算错误的奇数和偶数
//比如若为奇数,那么对应的位置应该也是奇数
if(i%2==0 && a[i]%2)
odd++;
if(i%2 && a[i]%2==0)
even++;
}
//2.判断
//如果错误个数相同,那么就说明可以交换
//并且交换次数就等于错误个数
if(odd == even)
{
cout<<odd<<endl;
}
else
cout<<-1<<endl;
}
return 0;
}
5.今年暑假不AC
题目来源,点击查看
题目分析:给定每个节目的开始时间和结束时间,输出能看到完整电视节目的最多个数
解题思路:按照节目的结束时间进行排序,让每个节目的开始时间和选定的最后一个节目的结束时间对比,若是>=,那么不会重合,那么节目数量num++;
代码示例:
#include <iostream>
#include <algorithm>
using namespace std;
typedef struct{
int Ti_s; //开始时间
int Ti_e; //结束时间
}WTime;
int main() {
int n;
WTime Ti[105];
while(scanf("%d",&n) && n)
{
for(int i=0;i<n;i++)
scanf("%d %d",&Ti[i].Ti_s ,&Ti[i].Ti_e );
//排序
//也可尝试用别的方法进行排序
for(int i=n-1;i>0;i--)
{
for(int j=0;j<i;j++)
{
if(Ti[j].Ti_e >Ti[j+1].Ti_e )
{
WTime temp=Ti[j];
Ti[j]=Ti[j+1];
Ti[j+1]=temp;
}
}
}
int num=1;
int curE=Ti[0].Ti_e ;
for(int i=0;i<n;i++)
{
//判断这个节目的开始时间是否>=选定的最后一个节目的结束时间
if(Ti[i].Ti_s >=curE)
{
num++;
curE=Ti[i].Ti_e ;
}
}
printf("%d\n",num);
}
return 0;
}