CodeChef December Challenge 2013 解题报告

Problem A Magic Pairs

水体一枚,其实就是求1-n-1的和。用long long 就行。

代码如下:

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <cstring>
 4 #include <cstdlib>
 5 #include <algorithm>
 6 #include <vector>
 7 #include <queue>
 8 #include <stack>
 9 #define LEN 101000
10 #define INF 0x7fffffff
11 #define ll long long
12 
13 using namespace std;
14 
15 int n, num[LEN];
16 
17 int main()
18 {
19 //    freopen("in.txt", "r", stdin);
20 
21     int T;
22     scanf("%d", &T);
23     while(T--){
24         scanf("%d", &n);
25         for(int i=0; i<n; i++){
26             scanf("%d", &num[i]);
27         }
28         ll ans = 0;
29         for(int i=n-1; i>0; i--){
30             ans+=i;
31         }
32         cout << ans << endl;
33     }
34     return 0;
35 }
View Code


Problem B Chef and Codes

字符串操作。有中文题就不说意思了。

有一点比较坑就是原来是大写的字母转换后输出来也必须也是大写的。其他都ok。

代码如下:

 1 #include <iostream>
 2 #include <cstring>
 3 #include <cstdio>
 4 #include <algorithm>
 5 #define LEN 101000
 6 
 7 using namespace std;
 8 
 9 struct Z{
10     int pos, num;
11 }z[50];
12 
13 bool cmp(Z a, Z b){
14     if(a.num!=b.num) return a.num<b.num;
15     else return a.pos<b.pos;
16 }
17 
18 int main()
19 {
20 //    freopen("in.txt", "r", stdin);
21 
22     char str[LEN], dir[50], hash[50], flag[LEN];
23     int T;
24     scanf("%d", &T);getchar();
25     while(T--){
26         memset(z, 0, sizeof z);
27         memset(flag, 0, sizeof flag);
28         for(int i=0; i<26; i++){
29             z[i].pos = i;
30             dir[i] = getchar();
31         }
32         getchar();
33         gets(str);
34         for(int i=0; str[i]!=0; i++){
35             if(str[i]>='A' && str[i]<='Z'){
36                  str[i] = str[i]-'A'+'a';
37                  flag[i] = 1;
38             }
39             if(str[i]>='a' && str[i]<='z'){
40                 z[str[i]-'a'].num++;
41             }
42         }
43         sort(z, z+26, cmp);
44         for(int i=0; i<26; i++){
45             hash[z[i].pos] = dir[i];
46         }
47         hash[26] = 0;
48         for(int i=0; str[i]!=0; i++){
49             if(str[i]>='a' && str[i]<='z'){
50                 char cc = hash[str[i]-'a'];
51                 if(flag[i])cc = cc-'a'+'A';
52                 putchar(cc);
53             }
54             else
55                 putchar(str[i]);
56         }
57         putchar('
');
58     }
59     return 0;
60 }
View Code

Problem E Funny Marbles
线段树点更新,然后区间查询。直接用模版改一下然后就a掉了。

代码如下:

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <string.h>
 4 #include <algorithm>
 5 #define ll long long
 6 
 7 using namespace std;
 8 
 9 const int N = 1010000, MAX = 4*N;
10 ll BSTree[MAX];
11 
12 void Update(int l ,int r, int rt, int t, int data)
13 {
14     if(l==r && l==t){BSTree[rt] += data; return ;}
15     int mid = (l+r)>>1;
16     if(t<=mid) Update(l, mid, rt<<1,t,data);
17     if(t>mid)Update(mid+1 ,r, rt<<1|1, t, data);
18     BSTree[rt] = BSTree[rt<<1]+BSTree[rt<<1|1];
19 }
20 
21 ll Query(int l, int r, int rt, int tl, int tr)
22 {
23     if(l==tl && r == tr)return BSTree[rt];
24     int mid = (l+r)>>1;
25     if(tr<=mid)return Query(l, mid, rt<<1, tl, tr);
26     if(tl>mid)return Query(mid+1, r, rt<<1|1, tl, tr);
27     return Query(l, mid, rt<<1, tl, mid)+Query(mid+1, r, rt<<1|1, mid+1, tr);
28 }
29 
30 int main()
31 {
32 //    freopen("in.txt", "r", stdin);
33 
34     int n, q;
35     while(scanf("%d%d", &n, &q)!=EOF){
36         memset(BSTree, 0, sizeof(BSTree));
37         for(int i=1; i<=n; i++){
38             int temp;
39             scanf("%d", &temp);
40             Update(1,N,1,i,temp);
41         }
42         for(int i=0; i<q; i++){
43             int a, b;char c;
44             scanf("%s%d%d", &c, &a, &b);
45             if(c=='S'){
46                 printf("%lld
", Query(1,N,1,a+1,b+1));
47             }
48             else if(c=='G'){
49                 Update(1,N,1,a+1,b);
50             }
51             else {
52                 Update(1,N,1,a+1,-b);
53             }
54         }
55     }
56     return 0;
57 }
View Code

Problem H Rectangular Queries

水题一枚,直接统计从(1,1)-(i,j)中含有1-10的数字的个数,然后对于每次查询通过枚举每个数字有没有答案来确定答案。

代码如下:

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <cstring>
 4 #include <cstdlib>
 5 #include <algorithm>
 6 #include <utility>
 7 #include <vector>
 8 #include <queue>
 9 #include <stack>
10 #define INF 0x7fffffff
11 #define LEN 310
12 
13 using namespace std;
14 
15 int n, Map[LEN][LEN], dp[LEN][LEN][12];
16 int x1, x2, y1, y2;
17 
18 void init()
19 {
20     memset(dp, 0, sizeof dp);
21     for(int i=1; i<=n; i++){
22         for(int j=1; j<=n; j++){
23             for(int k=1; k<=10; k++){
24                 dp[i][j][k] = dp[i-1][j][k]+dp[i][j-1][k]-dp[i-1][j-1][k];
25             }
26             dp[i][j][Map[i][j]]++;
27         }
28     }
29 }
30 
31 int main()
32 {
33 //    freopen("in.txt", "r", stdin);
34 
35     while(scanf("%d", &n)!=EOF){
36         for(int i=1; i<=n; i++){
37             for(int j=1; j<=n; j++){
38                 scanf("%d", &Map[i][j]);
39             }
40         }
41         init();
42         int q;
43         scanf("%d", &q);
44         for(int i=0; i<q; i++){
45             scanf("%d%d%d%d", &x1, &y1, &x2, &y2);
46             int ans = 0;
47             for(int k=1; k<=10; k++){
48                 if(dp[x2][y2][k]-dp[x2][y1-1][k]-dp[x1-1][y2][k]+dp[x1-1][y1-1][k])
49                     ans++;
50             }
51             printf("%d
", ans);
52         }
53     }
54     return 0;
55 }
View Code

 Problem I Reign

由题意我们可以知道我们需要求相距大于k的两个子段使其两个子段和最大。很容易想到我们可以把数组分成两部分然后枚举分割点分别求其最大子段和即可。

由于数组长度要达10E5所以我们需要预处理两个数组,pre[i]表示i之前的最大子段和,las[i]表示i之后的最大子段和。这样就解出来了。

代码如下:

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <cstring>
 4 #include <algorithm>
 5 #include <stack>
 6 #include <queue>
 7 #include <vector>
 8 #include <utility>
 9 #define LEN 100100
10 #define INF 0x7fffffff
11 #define ll long long
12 
13 using namespace std;
14 
15 int n, k;
16 ll num[LEN], pre[LEN], las[LEN];
17 
18 void init(){
19     memset(pre, 0 ,sizeof pre);
20     memset(las, 0 ,sizeof las);
21     for(int i=1; i<=n; i++){
22         pre[i] = pre[i-1]<0?num[i]:pre[i-1]+num[i];
23     }
24     pre[0] = -INF;
25     for(int i=1; i<=n; i++)pre[i] = max(pre[i-1], pre[i]);
26     for(int i=n; i>=1; i--){
27         las[i] = las[i+1]<0?num[i]:las[i+1]+num[i];
28     }
29     las[n+1] = -INF;
30     for(int i=n; i>=1; i--)las[i] = max(las[i+1], las[i]);
31 }
32 
33 int main()
34 {
35 //    freopen("in.txt", "r", stdin);
36 
37     int T;
38     scanf("%d", &T);
39     while(T--){
40         scanf("%d%d", &n, &k);
41         for(int i=1; i<=n; i++){
42             cin >> num[i];
43         }
44         init();
45         ll ans = -INF;
46         for(int i=1; i+k<n; i++){
47             ans = max(ans, pre[i]+las[i+k+1]);
48         }
49         cout << ans << endl;
50     }
51     return 0;
52 }
View Code
奔跑吧!少年!趁着你还年轻
原文地址:https://www.cnblogs.com/shu-xiaohao/p/3463508.html