1. 程式人生 > >Codeforces Round #513-ABCD

Codeforces Round #513-ABCD

namespace .com 組成 set pre ret pen 不出 一位

ABC現場做出,漲了八十幾分吧。D有點思路不知道怎麽實現,賽後看題解發現巨簡單,想得太復雜了。藍瘦。

A----http://codeforces.com/contest/1060/problem/A

題意:給定n位數,問能組成多少電話號碼。電話號碼是一個以8位開頭的11位數

思路:統計一下8的個數,計算一下n/11的個數,兩者取較小值即為答案

技術分享圖片
 1 #include <bits/stdc++.h>
 2 #include<iostream>
 3 #include<cmath>
 4 #include<algorithm>
 5 #include<stdio.h>
 6
#include<cstring> 7 #include<map> 8 9 #define inf 0x3f3f3f3f 10 using namespace std; 11 typedef long long int LL; 12 13 int n; 14 const int maxn = 105; 15 int dig[10]; 16 17 int main() 18 { 19 while(scanf("%d", &n) != EOF){ 20 char str[maxn]; 21 scanf("%s", str);
22 memset(dig, 0, sizeof(dig)); 23 int cnt = 0; 24 for(int i = 0; i < n; i++){ 25 dig[str[i] - 0]++; 26 cnt++; 27 } 28 29 int ans = min(dig[8], cnt / 11); 30 cout<<ans<<endl; 31 } 32 return 0; 33 }
View Code

B---http://codeforces.com/contest/1060/problem/B

題意:給定一個n,要求兩個數 a+b=n並且a的各數位之和和b的各數位之和相加是最大的,輸出這個和

思路:有一個數一定是比n少一位的,全由9構成的數。

技術分享圖片
 1 #include <bits/stdc++.h>
 2 #include<iostream>
 3 #include<cmath>
 4 #include<algorithm>
 5 #include<stdio.h>
 6 #include<cstring>
 7 #include<map>
 8 
 9 #define inf 0x3f3f3f3f
10 using namespace std;
11 typedef long long int LL;
12 
13 LL n;
14 
15 int main()
16 {
17     while(scanf("%I64d", &n) != EOF){
18         int dig = 0;
19         LL tmp = n;
20         while(tmp){
21             tmp /= 10;
22             dig++;
23         }
24 
25         dig--;
26         int ans = dig * 9;
27         tmp = n;
28         LL ten = 1;
29         while(dig){
30             tmp -= ten * 9;
31             ten *= 10;
32             dig--;
33         }
34         while(tmp){
35             ans += tmp % 10;
36             tmp /=10;
37         }
38         printf("%d\n", ans);
39     }
40     return 0;
41 }
View Code

C---http://codeforces.com/contest/1060/problem/C

題意:給定兩個數組a和b,矩陣c(i,j) = ai * bj,求矩陣c的一個子矩陣使得子矩陣中所有元素和小於x,並且要讓這個子矩陣的元素個數盡可能多

思路:c是不需要算出來的。找c的一個子矩陣相當於分別找a和b中連續的一段區間。

首先預處理出a和b中,連續的長度為i的區間之和最小的。asum[i]即為a數組中,連續的長度為i的總和最小的區間

因為要讓元素個數盡可能多,那麽就應該要找和最小值

然後分別枚舉子矩陣的行數和列數,找到和小於x且元素個數最多的

技術分享圖片
 1 #include <bits/stdc++.h>
 2 #include<iostream>
 3 #include<cmath>
 4 #include<algorithm>
 5 #include<stdio.h>
 6 #include<cstring>
 7 #include<map>
 8 
 9 #define inf 0x3f3f3f3f
10 using namespace std;
11 typedef long long int LL;
12 
13 int n, m;
14 const int maxn = 2005;
15 LL a[maxn], b[maxn], x;
16 LL suma[maxn], sumb[maxn];
17 LL asum[maxn], bsum[maxn];
18 
19 int main()
20 {
21     while(scanf("%d%d", &n, &m) != EOF){
22         memset(suma, 0, sizeof(suma));
23         memset(sumb, 0, sizeof(sumb));
24         for(int i = 1; i <= n; i++){
25             scanf("%I64d", &a[i]);
26             suma[i] = suma[i - 1] + a[i];
27         }
28         for(int i = 1; i <= m; i++){
29             scanf("%I64d", &b[i]);
30             sumb[i] = sumb[i - 1] + b[i];
31         }
32         scanf("%I64d", &x);
33 
34         memset(asum, inf, sizeof(asum));
35         memset(bsum, inf, sizeof(bsum));
36         for(int i = 1; i <= n; i++){
37             for(int pos = i; pos <= n; pos++){
38                 asum[i] = min(suma[pos] - suma[pos - i], asum[i]);
39             }
40         }
41         for(int i = 1; i <= m; i++){
42             for(int pos = i; pos <= m; pos++){
43                 bsum[i] = min(sumb[pos] - sumb[pos - i], bsum[i]);
44             }
45         }
46 
47         LL ans = 0;
48         for(int i = n; i >= 1; i--){
49             for(int j = m; j >= 1; j--){
50                 if(bsum[j] * asum[i] <= x){
51                     if(i * j > ans){
52                         ans = i * j;
53                     }
54                 }
55             }
56         }
57 
58         printf("%I64d\n", ans);
59     }
60     return 0;
61 }
View Code

D---http://codeforces.com/contest/1060/problem/D

題意:有n個人坐成一圈 每個人都要求他的左邊至少有a[i]個空位,右邊有b[i]個空位。問要滿足所有人的要求至少需要多少凳子。

思路:

現場的思路是所有人和空位之和。每次都找到左邊空位最大的那個人,和右邊空位最大的那個進行合並,總數就減去。合並之後相當於形成一個新的人。但是一時想不出來我形成新的人之後要怎麽繼續維護,難道每次都排序,肯定是不夠的。

其實,合並並沒有影響左邊的數組和右邊的數組。合並之後的左邊和右邊原來就在數組之中。

所以只需要先對a和b數組分別排序,每次取出a和b中的最大值。答案加上這兩個最大之中的較大。最後答案加上n就行了。

技術分享圖片
 1 #include <bits/stdc++.h>
 2 #include<iostream>
 3 #include<cmath>
 4 #include<algorithm>
 5 #include<stdio.h>
 6 #include<cstring>
 7 #include<map>
 8 
 9 #define inf 0x3f3f3f3f
10 using namespace std;
11 typedef long long LL;
12 
13 int n;
14 const int maxn = 1e5 + 5;
15 int a[maxn], b[maxn];
16 
17 int main()
18 {
19     while(scanf("%d", &n) != EOF){
20         for(int i = 0; i < n; i++){
21             scanf("%d%d", &a[i], &b[i]);
22         }
23         sort(a, a + n);
24         sort(b, b + n);
25 
26         LL ans = n;
27         for(int i = 0; i < n; i++){
28             ans += max(a[i], b[i]);
29         }
30         printf("%I64d\n", ans);
31     }
32     return 0;
33 }
View Code

Codeforces Round #513-ABCD