认真读题
貌似贪心算法中很多要进行排序的
----------------------------------------------------------------------------
http://acm.nyist.net/JudgeOnline/problem.php?pid=71
先把各个人的体重排序,然后计算最重的人和最轻的人能否同乘一条舟,如果不能,则最重的人就要单独乘坐一条舟,再求最轻的和第二重的人的和,依次比较。
#include <stdio.h> #include <stdlib.h> #include <string.h> int cmp_1(const void *a, const void *b) { return *(int *)a - *(int *)b; } int main() { int n; int max_weight; int people_num; int people_weight[300]; int i; int rear; int boat_num; scanf("%d", &n); while (n--) { boat_num = 0; memset(people_weight, 0, sizeof(people_weight)); scanf("%d%d", &max_weight, &people_num); rear = people_num - 1; for (i = 0; i < people_num; i++) { scanf("%d", &people_weight[i]); } //对人的重量进行排序 qsort(people_weight, people_num, sizeof(people_weight[0]), cmp_1); for (i = 0; i <= rear;) { if (i != rear) { if (people_weight[i] + people_weight[rear] <= max_weight) { boat_num++; rear--; i++; } else { if (people_weight[i] >= people_weight[rear]) { boat_num++; i++; } else { rear--; boat_num++; } } } else { boat_num++; break; } } printf("%d ", boat_num); } return 0; }
---------------------------------------------------------------------
http://acm.nyist.net/JudgeOnline/problem.php?pid=448
/* 首先是在source_num的前source_num_len - del_num_len + 1中取最大的数字 因为至少要剩下source_num_len - del_num_len位数字来补齐其余的数字 比如1 0 5 7 8 9 长度为7 要删除的数字个数是3 所以必须在前4位中找数字 即使最大的数字是第4个,还有剩下的数字能用来补全的 然后继续这样的循环 */
#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #include<cmath> using namespace std; int main() { int ncase; char s[110], ans[110]; int m, len, sign, max, num; scanf("%d", &ncase); while(ncase--) { num = sign = 0; scanf("%s%d", s, &m); len = strlen(s); for(int i = 0; i < len - m; ++i) //找m次最大值 { max = -1; for(int j = sign; j <= m + i; ++j) //j的范围不能错~保证位数 { if(max < s[j] - '0') { max = s[j] - '0'; sign = j; } } ans[num++] = s[sign++]; } for(int i = 0; i < len - m; ++i) cout<<ans[i] - '0'; cout<<endl; } return 0; }
------------------------------------------------------------------------------------------------------
http://acm.nyist.net/JudgeOnline/problem.php?pid=6
自己画图看看就行
算出 这个草地的斜边长度, 然后只要全部圆的半径合大于等于这个斜边长度的一半就可以了(但是必须丢弃半径小于等于1的装置,在横中线上无论怎么放,它是无法完全覆盖草地的)。
#include <cstdio> #include <cstdlib> #include <cmath> int compare (const void * a, const void * b) { return *(double *)b > *(double *)a ? 1 : -1; } int main( int argc, char **argv ) { int n; scanf("%d", &n); double buf[600]; // 草地斜边长度的一半 double len = sqrt(20*20 + 2*2)/2; while ( n-- ) { int m; scanf("%d", &m); for ( int i = 0; i < m; ++i ) scanf("%lf", buf+i); // 从大到小排 qsort (buf, m, sizeof(buf[0]), compare); double sum = 0; int i; for ( i = 0; i < m; ++i ) { if (buf[i] <= 1) break; sum += buf[i]; if ( sum >= len ) // 半径和大于等于草地斜边长度一半就满足条件了 break; } printf( "%d ", i+1); } return 0; }