Codeforces Round #437 (Div. 2)
codeforces 867 A. Between the Offices(水)
题意:已知白天所在地(晚上可能坐飞机飞往异地),问是否从西雅图飞到旧金山次数更多。
题解:只要判断第一天和最后一天状态即可。
1 #include<cstdio> 2 #include<cstring> 3 #include<algorithm> 4 using namespace std; 5 const int N = 101; 6 int n; 7 char s[N]; 8 int main() { 9 scanf("%d %s", &n, s); 10 if(s[0] == 'S' && s[n-1] == 'F') puts("YES"); 11 else puts("NO"); 12 return 0; 13 }
codeforces 865 A. Save the problem!(构造)
题意:原本是知道所需钱数和有多少种类的面额以及各面额的价值,要求有多少种方式可以从给定的面额中选取若干拼成所需的钱数,,现在反过来已知多少方式,来构造输入样例。
题解:直接用1和2面额来拼。
1 #include<cstdio> 2 #include<cstring> 3 #include<algorithm> 4 using namespace std; 5 int n; 6 int main() { 7 scanf("%d", &n); 8 printf("%d 2 1 2 ", (n-1)*2+1); 9 return 0; 10 }
codeforces 865 B. Ordering Pizza(贪心)
题意:有两种类型的披萨,已知有N个人要吃披萨,每块披萨有S片;第i个人吃si片,如果吃类型1,每片能获得ai幸福度,吃类型2则是bi幸福度。现在要购买最少数量的披萨满足N个人所需的数量,并求能获得的最大幸福度。
题解:贪心吃幸福度大的类型,记录1、2类型最优各吃几片,如果1、2类型披萨所需数量之和≤总共所需披萨数量,则直接输出答案,否则给 1和2类型幸福度差值较小的赋予高优先级,排序后 将多余的1类型换成2类型披萨,或2换成1,以满足最少数量披萨数目。
1 #include<cstdio> 2 #include<cstring> 3 #include<algorithm> 4 using namespace std; 5 typedef long long ll; 6 const int N = 1e5+1; 7 ll n, S; 8 ll s[N],a[N],b[N]; 9 struct node { 10 ll x; 11 int id; 12 bool operator < (const node&r)const{ 13 return x < r.x; 14 } 15 }c[N]; 16 int main() { 17 int i, f = 0; 18 ll ans = 0, sum = 0, a1=0, a2=0; 19 ll s1=0, s2=0; 20 scanf("%lld %lld", &n, &S); 21 for(i = 1; i <= n; ++i) { 22 scanf("%lld %lld %lld", &s[i], &a[i], &b[i]); 23 if(a[i] > b[i]) s1 += s[i]; 24 else if(a[i] < b[i]) s2 += s[i]; 25 sum += s[i]; 26 ans += max(a[i], b[i]) * s[i]; 27 c[i].x = a[i] - b[i]; c[i].id = i; 28 } 29 ll cnt = (sum + S-1) /S; 30 if((s1 + S-1)/S + (s2 + S-1)/S <= cnt) {printf("%lld", ans); return 0;} 31 sort(c+1, c+1+n); 32 s1 %= S; s2 %= S; 33 for(i = 1; i <= n; ++i) { 34 if(c[i].x <= 0) {f = i; continue;} 35 if(!s1) break; 36 ll t = min(s[c[i].id], s1); 37 a1 += t * c[i].x; 38 s1 -= t; 39 } 40 for(i = f; i >= 1; --i) { 41 if(!c[i].x) continue; 42 if(!s2) break; 43 ll t = min(s[c[i].id], s2); 44 a2 -= t * c[i].x; 45 s2 -= t; 46 } 47 printf("%lld ", ans - min(a1, a2)); 48 return 0; 49 }
codeforces 865 D. Buy Low Sell High(优先队列,模拟)
题意:知道N天的股票的价格,一开始有0股,每天可以买一股或卖一股或什么都不做,要在N天后继续是0股,但希望在这N天内赚尽量多的钱。
题解:开个优先队列模拟。注意优先队列默认数据大的优先级高,所以加个负号。
比队首大的值要插入两遍,一是为了给前面小的值升值,二是为了将自己插入队列等待被买入。比如:4、7、9,4被升值为7进而被升值为9(实际选择是-4+9),第二步取出的一个7是为了给4进一步升值,7还要有一个在队列中等待被买入。
1 #include<cstdio> 2 #include<cstring> 3 #include<algorithm> 4 #include<queue> 5 using namespace std; 6 priority_queue<int> q; 7 int main() { 8 int i, n, x; 9 long long ans = 0; 10 scanf("%d", &n); 11 q.push(-1000001); 12 for(i = 1; i <= n; ++i) { 13 scanf("%d", &x); 14 if(-q.top() < x) { 15 ans += x + q.top(); q.pop(); q.push(-x); 16 } 17 q.push(-x); 18 } 19 printf("%lld", ans); 20 return 0; 21 }