分糖果
http://oj.haizeix.com/problem/750 现在有 n 个正整数,将他们连成一排,组成一个最大的整数。
v1
一个较为复杂的思路:理解题目,可以发现从左往右分糖果,如果下一个孩子评分更高,则该孩子的糖果数就+1。
比如序列1 2 3 我们分配的糖果也是1 2 3
循环中遇到的另一种情况就是下一个孩子评分更低的情况,这时候可以认为他该分的糖果数为1。
此时需要反过来考虑当前这个孩子是否为1,此时需要从右往左开始考虑,反过来把之前的数字加1。
#include<iostream>
using namespace std;
int main(){
int n;
cin>>n;
int *a = new int[n];
int *b = new int[n];
for(int i=0;i<n;i++)
cin>>a[i];
b[0] = 1;
for(int i=1;i<n;i++){
if(a[i]>a[i-1]){
b[i]=b[i-1]+1;
}
if(a[i]==a[i-1]){
b[i] = b[i-1];
}
if(a[i]<a[i-1]){
b[i] = 1;
if(b[i-1]<=1){
//cout<<"!!!";
int j=i-1;
b[j]++;
while((j-1)>=0 && b[j-1]-b[j]==0){
j--;
b[j]++;
}
}
}
}
int num=0;
for(int i=0;i<n;i++)
num+=b[i];
cout<< num;
//cout<<b[i]<<" ";
delete a;
return 0;
}
v2
简单点的思路是为了保证评分高的孩子获得比评分低的多,这里注意的点是相邻的,因此只用管相邻的就好了。从左到右遍历一次,遇到更大的就加一,否则就置为1。然后从右到左也来一次,方式和第一次相同。此时和,对于每一个小孩来说,需要的糖果数就是这两次遍历中的最大值。这是由于此时该最大值必然会同时满足以上这两种情况。
#include<iostream>
#include<vector>
#include<algorithm>
using namespace std;
int main(){
int n;
cin>>n;
vector<int> rating(n);
vector<int> num(n);
for(int i=0; i<n; i++){
int data;
cin >> data;
rating[i] = data;
}
num[0] = 1;
for(int i=1;i<n;i++){
if(rating[i]>rating[i-1])
num[i]=num[i-1]+1;
else
num[i] = 1;
//cout<<"!!"<<num[i]<<" ";
}
int right=0;
for(int i=n-1;i>=0;i--){
if(i < n-1 && rating[i]>rating[i+1])
right++;
else
right=1;
//printf("! %d %d",i,right);
num[i] = max(num[i],right);
}
int ans=0;
for(int i=0;i<n;i++){
ans += num[i];
//cout<<" "<<num[i];
}
printf("%d",ans);
return 0;
}
分饼干
http://oj.haizeix.com/problem/749 假设你是一位很棒的家长,想要给你的孩子们一些小饼干。但是,每个孩子最多只能给一块饼干。
为了尽可能满足最多数量的孩子,从贪心的角度考虑,应该按照孩子的胃口从小到大的顺序依次满足每个孩子,且对于每个孩子,应该选择可以满足这个孩子的胃口且尺寸最小的饼干。(下面的代码实现使用的是从大到小排序,道理相同~)
#include<iostream>
#include<stdlib.h>
using namespace std;
int compare(const void *a, const void *b)
{
unsigned int *pa = (unsigned int*)a;
unsigned int *pb = (unsigned int*)b;
return (*pb) - (*pa );
}
int main(){
unsigned int na,nb;
cin>>na;
int *a = new int[na];
for(int i=0;i<na;i++)
cin>>a[i];
cin>>nb;
int *b = new int[nb];
for(int i=0;i<nb;i++)
cin>>b[i];
//cout<<"!~!";
qsort(a,na,sizeof(unsigned int),compare);
qsort(b,nb,sizeof(unsigned int),compare);
//cout<<"!~!";
int j=0,i=0,num=0;
for(;i<na && j<nb;i++){
//cout<<b[j]<<" "<<a[i]<<endl;
if(b[j]>=a[i]){
j++;
num++;
}
}
cout<<num;
return 0;
}
最大整数
http://oj.haizeix.com/problem/505 现在有 n 个正整数,将他们连成一排,组成一个最大的整数。
这个问题的主要思路也是贪心。每一次我都把尽可能”大“的最大数排在前面,这样连接起来的数肯定是最大的。
”大“的判断比较特殊,需要是让两两组合后,能够使得组合后数字较大的数。
- 这道题的解题思路和对于vector, sort的使用可以好好学习一下。
#include<iostream>
#include<vector>
#include<algorithm>
using namespace std;
bool cmp(const string &a, const string &b){
return a+b > b+a; //这种比较就是会使得最前面的数组合任意数都可以达到最大。
}
int main(){
int n;
cin >> n;
vector <string> nums(n);
for(int i; i<n; i++)
cin>>nums[i];
sort(nums.begin(), nums.end(), cmp);
string ans;
for(int i = 0; i < nums.size(); i++){
ans += nums[i];
}
cout << ans << endl;
return 0;
}