UVA 11292 The Dragon of Loowater(简单贪心)
题意:
n条恶龙,m个勇士,用勇士来杀恶龙。一个勇士只能杀一个恶龙。而且勇士只能杀直径不超过自己能力值的恶龙。每个勇士需要支付能力值一样的金币。问杀掉所有恶龙需要的最少金币。
1 #include <bits/stdc++.h> 2 using namespace std; 3 const int maxn = 20000 + 5; 4 int n, m; 5 int night[maxn], dragon[maxn]; 6 void solve() 7 { 8 int cost = 0; 9 int cur = 0; 10 for(int i = 0; i < m; i++) 11 { 12 if(night[i] >= dragon[cur]) 13 { 14 cost += night[i]; 15 if(++cur == n) 16 { 17 printf("%d\n", cost); 18 return ; 19 } 20 } 21 } 22 printf("Loowater is doomed!\n"); 23 return ; 24 } 25 int main() 26 { 27 while(~scanf("%d%d", &n, &m)) 28 { 29 if(n + m == 0) break; 30 for(int i = 0; i < n; i++) 31 scanf("%d", &dragon[i]); 32 for(int j = 0; j < m; j++) 33 scanf("%d", &night[j]); 34 sort(dragon, dragon + n); 35 sort(night, night + m); 36 solve(); 37 } 38 return 0; 39 }
UVA 11729 Commando War(经典贪心)
题意:
n个任务,需要交代B分钟,执行J分钟,让你合理选择交代任务的次序,求得n个任务完成的最小总时长
#include <bits/stdc++.h> using namespace std; const int maxn = 10000 + 5; const int INF = 0x3f3f3f3f; int n, Cas; int sum[maxn]; struct node { int j, b; bool operator < (const node &other)const { return j > other.j; } }a[maxn]; void solve() { Cas ++; sort(a, a + n); sum[0] = a[0].b; for(int i = 1; i < n; i++) { sum[i] = sum[i - 1] + a[i].b; } int maxx = 0; for(int i = 0; i < n; i++) { sum[i] += a[i].j; maxx = max(maxx, sum[i]); } printf("Case %d: %d\n", Cas, maxx); } int main() { Cas = 0; while(~scanf("%d", &n) && n) { for(int i = 0; i < n; i++) { scanf("%d%d", &a[i].b, &a[i].j); } solve(); } return 0; }
UVA 11300 Spreading the Wealth (数学推导)
题意:
n个人围成一圈,每个人都有一些硬币,,每个人只能给左右相邻的人硬币,问最少交换几个硬币,使每个人硬币一样多;
1 #include <bits/stdc++.h> 2 using namespace std; 3 typedef long long LL; 4 const int maxn = 1000000 + 5; 5 const int INF = 0x3f3f3f3f; 6 int n, Cas; 7 LL a[maxn], c[maxn]; 8 9 int main() 10 { 11 while(~scanf("%d", &n)) 12 { 13 LL sum = 0; 14 for(int i = 0; i < n; i++) 15 { 16 scanf("%lld", &a[i]); 17 sum += a[i]; 18 } 19 LL ave = sum / n; 20 c[0] = a[0] - ave; 21 for(int i = 1; i < n; i++) 22 { 23 c[i] = c[i - 1] + a[i] - ave; 24 } 25 sort(c, c + n); 26 LL ans = 0, d = c[n / 2]; 27 for(int i = 0; i < n; i++) 28 { 29 ans += abs(c[i] - d); 30 } 31 printf("%lld\n", ans); 32 } 33 return 0; 34 }
UVA 10881 Piotr‘s Ants(思维?)
题意:
有很多只蚂蚁在一条直线上,每个蚂蚁移动速度都是1,并且有一个初始方向。并且当相邻两个蚂蚁相撞时转向。现在问t时间后各个蚂蚁的位置,及状态。
1 #include <stdio.h> 2 #include <bits/stdc++.h> 3 using namespace std; 4 const int mod = 1e9 + 7; 5 const int maxn = 10000 + 5; 6 const int INF = 0x3f3f3f3f; 7 typedef long long LL; 8 typedef pair<int, int>pii; 9 typedef pair<LL, LL>pLL; 10 typedef unsigned long long ull; 11 12 struct node 13 { 14 int id, pos, d;//这个id是输入数据的顺序 15 bool operator < (const node &other)const 16 { 17 return pos < other.pos; 18 } 19 }before[maxn], after[maxn]; 20 int order[maxn];//这个是蚂蚁在绳索上的相对顺序 21 const char dirName[][10] = {"L", "Turning", "R"}; 22 23 int main() 24 { 25 int Test; 26 scanf("%d", &Test); 27 for(int cas = 1; cas <= Test; cas++) 28 { 29 int L, T, n; 30 scanf("%d%d%d", &L, &T, &n); 31 for(int i = 0; i < n; i++) 32 { 33 int pos; 34 char dir; 35 scanf("%d %c", &pos, &dir); 36 int d = (dir == ‘L‘) ? -1 : 1;//L -1 R 1 37 before[i] = {i, pos, d}; 38 after[i] = {0, pos + T * d, d}; 39 } 40 41 sort(before, before + n); 42 for(int i = 0; i < n; i++) 43 { 44 order[before[i].id] = i; 45 }//order 记录 蚂蚁在绳索上的顺序 46 47 sort(after, after + n); 48 for(int i = 0; i < n - 1; i++) 49 { 50 if(after[i].pos == after[i + 1].pos) after[i].d = after[i + 1].d = 0; 51 } 52 printf("Case #%d:\n", cas); 53 for(int i = 0; i < n; i++) 54 { 55 int num = order[i]; 56 if(after[num].pos < 0 || after[num].pos > L) puts("Fell off"); 57 else printf("%d %s\n", after[num].pos, dirName[after[num].d + 1]); 58 } 59 puts(""); 60 } 61 return 0; 62 }
UVA 11636 Hello World(思维 or 简单贪心)
题意:经过复制/粘贴可以变成原来的两倍,求最小复制/粘贴次数。
1 #include <stdio.h> 2 #include <bits/stdc++.h> 3 using namespace std; 4 const int mod = 1e9 + 7; 5 const int maxn = 1000000 + 5; 6 const int INF = 0x3f3f3f3f; 7 typedef long long LL; 8 typedef unsigned long long ull; 9 10 int main() 11 { 12 int n ,cas = 1; 13 while(~scanf("%d", &n)) 14 { 15 if(n < 0) break; 16 17 int ans = 0, temp = 1; 18 while(n > temp) 19 { 20 temp <<= 1; 21 ans++; 22 } 23 printf("Case %d: %d\n", cas ++, ans); 24 } 25 return 0; 26 }
UVA 11039 Building designing(贪心)
题意:
n个绝对值各不相同的非0整数,选出尽量多的数,排成一个序列,使得正负号交替且绝对值递增。
思路:
按绝对值排序,然后间次输出正负数即可。
1 #include <stdio.h> 2 #include <bits/stdc++.h> 3 using namespace std; 4 const int mod = 1e9 + 7; 5 const int maxn = 500000 + 5; 6 const int INF = 0x3f3f3f3f; 7 typedef long long LL; 8 typedef unsigned long long ull; 9 10 int a[maxn]; 11 bool cmp(int &x, int &y) 12 { 13 return abs(x) < abs(y); 14 } 15 int main() 16 { 17 int t; 18 scanf("%d", &t); 19 while(t--) 20 { 21 int n; 22 scanf("%d", &n); 23 for(int i = 0; i < n; i++) 24 { 25 scanf("%d", &a[i]); 26 } 27 sort(a, a + n, cmp); 28 int last = a[0] > 0, len = 1; 29 for(int i = 1; i < n; i++) 30 { 31 int temp = a[i] > 0; 32 if(last != temp) 33 { 34 last = temp; 35 len++; 36 } 37 } 38 cout << len << "\n"; 39 } 40 return 0; 41 }
UVA 10970 Big Chocolate(思维)
题意:
给你一块M*N的巧克力,问把它切成最小单元需要最少切几刀,分开的就不能一起切了。
思路:
每次下刀,只能多增加一块,一共需要切成m*n块,所以显然答案。
1 #include <stdio.h> 2 #include <bits/stdc++.h> 3 using namespace std; 4 const int mod = 1e9 + 7; 5 const int maxn = 1000000 + 5; 6 const int INF = 0x3f3f3f3f; 7 typedef long long LL; 8 typedef unsigned long long ull; 9 10 11 int main() 12 { 13 int n, m; 14 while(cin >> n >> m) cout << n * m - 1 << endl; 15 return 0; 16 }
UVA 10340 All in All(经典问题!)
题意:
从字符串s中删除一些字符,能否得到字符串t。
1 #include <stdio.h> 2 #include <bits/stdc++.h> 3 using namespace std; 4 const int mod = 1e9 + 7; 5 const int maxn = 1000000 + 5; 6 const int INF = 0x3f3f3f3f; 7 typedef long long LL; 8 typedef unsigned long long ull; 9 10 bool solve(string &s, string &t) 11 {//从t中删除 能否得到s 12 int lens = s.length(), lent = t.length(); 13 int cnt = 0; 14 for(int i = 0; i < lent; i++) 15 { 16 if(s[cnt] == t[i]) cnt++; 17 } 18 return cnt == lens; 19 } 20 21 int main() 22 { 23 string a, b; 24 while(cin >> a >> b) 25 { 26 printf("%s\n", solve(a, b) ? "Yes" : "No"); 27 } 28 return 0; 29 }
UVA 10382 Watering Grass(经典贪心)
题意:
有一块草坪,长为l,宽为w,在它的水平中心线上有n个位置可以安装喷水装置,各个位置上的喷水装置的覆盖范围为以它们自己的半径ri为圆。求出最少需要的喷水装置个数。
思路:
每个圆,和草坪边界交点,化成一个线段,然后问题就变成,最少需要几个小区间覆盖整个大区间。
1 #include <stdio.h> 2 #include <bits/stdc++.h> 3 using namespace std; 4 const int mod = 1e9 + 7; 5 const int maxn = 10000 + 5; 6 const int INF = 0x3f3f3f3f; 7 const double eps = 1e-8; 8 typedef pair<int, int>pii; 9 typedef pair<double, double>pdd; 10 typedef long long LL; 11 typedef unsigned long long ull; 12 13 int n, l; 14 double w; 15 pdd a[maxn]; 16 17 bool cmp(pii x, pii y) 18 { 19 if(x.first != y.first) return x.first < y.first; 20 return x.second < y.second; 21 } 22 23 int solve() 24 { 25 double last, temp; 26 if(a[0].first - 0 > eps) return -1; 27 28 int ans = 0; 29 double cur = 0, far = 0; 30 for(int i = 0; i < n; i++) 31 { 32 if(cur >= l) return ans; 33 if(a[i].first <= cur) 34 { 35 far = max(far, a[i].second); 36 } 37 else if(a[i].first > cur) 38 { 39 ans++; 40 cur = far; 41 if(a[i].first <= cur) 42 { 43 far = max(far, a[i].second); 44 } 45 else 46 { 47 return -1; 48 } 49 } 50 } 51 if(cur < l && far >= l) return ans + 1; 52 if(far < l) return -1; 53 return ans; 54 } 55 56 int main() 57 { 58 59 while(~scanf("%d%d%lf", &n, &l, &w)) 60 { 61 for(int i = 0; i < n; i++) 62 { 63 double pos, r; 64 scanf("%lf%lf", &pos, &r); 65 double d = sqrt(r * r - w / 2 * w / 2); 66 a[i].first = pos - d, a[i].second = pos + d; 67 } 68 sort(a, a + n, cmp); 69 70 cout << solve() << endl; 71 72 73 } 74 return 0; 75 }
UVA 10905 Children‘s Game(贪心)
题意:
给n个数字,将它们重新排序得到一个最大的数字,比如给出123 456 789 拼为 789456123 最大。
思路:
两两贪心!
1 #include <bits/stdc++.h> 2 using namespace std; 3 const int mod = 1e9 + 7; 4 const int maxn = 50 + 5; 5 const int INF = 0x3f3f3f3f; 6 typedef long long LL; 7 typedef unsigned long long ull; 8 9 10 string num[maxn]; 11 bool cmp(string &a, string &b) 12 { 13 return a + b > b + a; 14 } 15 int main() 16 { 17 int n; 18 while(~scanf("%d", &n)) 19 { 20 if(n == 0) break; 21 for(int i = 0; i < n; i++) 22 { 23 cin >> num[i]; 24 } 25 sort(num, num + n, cmp); 26 for(int i = 0; i < n; i++) 27 { 28 cout << num[i]; 29 } 30 puts(""); 31 } 32 33 return 0; 34 }
UVA 11134 Fabled Rooks(贪心)
题意:
在一个n*n(1<=n<=5000)的棋盘上放置n个车,每个车都只能在给定的一个矩形里放置,使其n个车两两不在同一行和同一列,判断并给出解决方案。
思路:
转换!这个问题可以分解成x方向上的问题,和相似的y方向上的问题。然后这个问题就转换成很经典的问题了,记不记得《挑战》奶牛擦防晒霜那题,经典的适配有上下边界的贪心。
1 #include <stdio.h> 2 #include <bits/stdc++.h> 3 using namespace std; 4 const int mod = 1e9 + 7; 5 const int maxn = 5000 + 5; 6 const int INF = 0x3f3f3f3f; 7 typedef long long LL; 8 typedef pair<int, int>pii; 9 typedef pair<LL, LL>pLL; 10 typedef unsigned long long ull; 11 12 struct node 13 { 14 int le, ri, order; 15 bool operator < (const node &other)const 16 { 17 return le < other.le || (le == other.le && ri < other.ri); 18 } 19 }x[maxn], y[maxn]; 20 int ansx[maxn], ansy[maxn]; 21 22 bool solve(int n, node z[], int ans[]) 23 { 24 sort(z, z + n); 25 priority_queue<pii, vector<pii>, greater<pii>>que; 26 int cnt = 0, ret = 0; 27 for(int i = 1; i <= n; i++) 28 { 29 while(cnt < n && z[cnt].le <= i) 30 { 31 que.push({z[cnt].ri, z[cnt].order}); 32 cnt++; 33 } 34 if(que.size() == 0) return false; 35 36 pii p = que.top(); 37 if(p.first < i) return false; 38 ans[p.second] = i; 39 que.pop(); 40 ret++; 41 } 42 return ret == n; 43 } 44 45 int main() 46 { 47 int n; 48 while(~scanf("%d", &n)) 49 { 50 if(n == 0) break; 51 for(int i = 0; i < n; i++) 52 { 53 scanf("%d%d%d%d", &x[i].le, &y[i].le, &x[i].ri, &y[i].ri); 54 x[i].order = y[i].order = i; 55 } 56 if(solve(n, x, ansx) && solve(n, y, ansy)) 57 { 58 for(int i = 0; i < n; i++) 59 { 60 printf("%d %d\n", ansx[i], ansy[i]); 61 } 62 } 63 else puts("IMPOSSIBLE"); 64 } 65 return 0; 66 }
UVA 11100 The Trip(简单思维)
题意:
n个旅行箱,形状相同,尺寸不同,尺寸小的可以放在尺寸大的旅行箱里。现在要求露在最外面的旅行箱的数量最少的同时满足一个旅行箱里放的旅行箱的数量最少。求出这样满足要求的任意一种方案。
思路:
这题很恶心!!!白书上的描述少了一个,一个旅行箱中的旅行箱最少的条件。然后就很水笔了。
vector忘记清了!!!
1 /* 2 vector忘记清了。。 3 */ 4 #include <stdio.h> 5 #include <bits/stdc++.h> 6 using namespace std; 7 const int mod = 1e9 + 7; 8 const int maxn = 10000 + 5; 9 const int INF = 0x3f3f3f3f; 10 typedef pair<int, int>pii; 11 typedef long long LL; 12 typedef unsigned long long ull; 13 14 int a[maxn]; 15 vector<int>vec[maxn]; 16 17 int main() 18 { 19 int n; 20 while(~scanf("%d", &n)) 21 { 22 if(n == 0) break; 23 map<int, int>ma; 24 int num = 0; 25 for(int i = 0; i < n; i++) 26 { 27 scanf("%d", &a[i]); 28 ma[a[i]]++; 29 num = max(num, ma[a[i]]); 30 } 31 for(int i = 0; i < num; i++) vec[i].clear(); 32 sort(a, a + n); 33 for(int i = 0; i < n; i++) 34 { 35 vec[i % num].push_back(a[i]); 36 } 37 38 printf("%d\n", num); 39 for(int i = 0; i < num; i++) 40 { 41 int temp = 0; 42 for(auto o : vec[i]) 43 { 44 printf("%d%c", o, ++temp == vec[i].size() ? ‘\n‘ : ‘ ‘); 45 } 46 } 47 } 48 return 0; 49 }
UVA 11389 The Bus Driver Problem(简单贪心)
题意:
有n个上午的任务和下午的任务,分配给司机,如果工作总时间超过d,超过的部分要给加班费;现在让你安排任务,问最小的加班分花费。
思路:
排序一下,首尾加一下就好了。
1 #include <bits/stdc++.h> 2 using namespace std; 3 const int mod = 1e9 + 7; 4 const int maxn = 100 + 5; 5 const int INF = 0x3f3f3f3f; 6 typedef long long LL; 7 typedef unsigned long long ull; 8 9 int day[maxn], night[maxn]; 10 11 int main() 12 { 13 int n, d, r; 14 while(~scanf("%d%d%d", &n, &d, &r)) 15 { 16 if(!n && !d && !r) break; 17 for(int i = 0; i < n; i++) 18 { 19 scanf("%d", &day[i]); 20 } 21 for(int i = 0; i < n; i++) 22 { 23 scanf("%d", &night[i]); 24 } 25 sort(day, day + n, greater<int>()); 26 sort(night, night + n, less<int>()); 27 28 LL sum = 0; 29 for(int i = 0; i < n; i++) 30 { 31 int temp = day[i] + night[i]; 32 if(temp > d) 33 { 34 sum += (temp - d) * r; 35 } 36 } 37 cout << sum << "\n"; 38 } 39 return 0; 40 }