• 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
    奔跑吧!少年!趁着你还年轻
  • 相关阅读:
    帧同步与状态同步的区别
    spread语法解析与使用
    CoordinatorLayout自定义Bahavior特效及其源码分析
    更便捷的Android多渠道打包方式
    用Dart&Henson玩转Activity跳转
    用RxJava处理复杂表单验证问题
    用RxJava处理嵌套请求
    技术与业务的抉择————论程序员的“瓶颈”问题
    Android Studio单元测试入门
    Android一键多渠道分发打包实战和解析
  • 原文地址:https://www.cnblogs.com/shu-xiaohao/p/3463508.html
Copyright © 2020-2023  润新知