1. 程式人生 > >Codeforces Round #437 (Div. 2)

Codeforces Round #437 (Div. 2)

std pro operator codeforce alt size pizza main 最後一天

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 }
15ms

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\n1 2\n", (n-1)*2+1);
 9     return 0;
10 }
15ms

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\n", ans - min(a1, a2));
48     return 0;
49 }
78ms

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     for(i = 1; i <= n; ++i) {
12         scanf("%d", &x);
13         if(!q.empty() && -q.top() < x) {
14             ans += x + q.top(); q.pop(); q.push(-x);
15         }
16         q.push(-x);
17     }
18     printf("%lld", ans);
19     return 0;
20 }
109ms

Codeforces Round #437 (Div. 2)