zoukankan      html  css  js  c++  java
  • 2018“氢舞杯”编程挑战赛2

    问题 N: 逆反的01串

    时间限制: 1Sec 内存限制: 128MB 提交: 10 解决: 7

    题目描述

    Fans是个ACM程序设计迷。有时侯,他表现出很强烈的逆反心理,你往东,他往西,你往南,他偏往北。这一次,不知道又是谁惹着他了,好端端的一个个01串,到了他的手里,都变成10串了。请你编个程序来模仿他的行为,将01串(长度≤200),全变成10串吧。

    输入
    0110100100100 1000000010000000000
    输出
    1001011011011 0111111101111111111
    思路:每一位取反
    #include<stdio.h> 
     
    int main() 
    { 
        char a[100];    
        while(gets(a)!=NULL){
              int i=0; 
            while(a[i]) 
             { 
              putchar(a[i] ^ 1); 
              i++; 
             } 
             printf("
    ");
        }
        return 0; 
    }
    
    

    问题 M: 能量项链

    时间限制: 1Sec 内存限制: 128MB 提交: 6 解决: 5

    题目描述

    在Mars星球上,每个Mars人都随身佩带着一串能量项链。在项链上有 N颗能量珠。能量珠是一颗有头标记与尾标记的珠子,这些标记对应着某个正整数。并且,对于相邻的两颗珠子,前一颗珠子的尾标记一定等于后一颗珠子的头标 记。因为只有这样,通过吸盘(吸盘是Mars人吸收能量的一种器官)的作用,这两颗珠子才能聚合成一颗珠子,同时释放出可以被吸盘吸收的能量。如果前一颗 能量珠的头标记为m,尾标记为r,后一颗能量珠的头标记为r,尾标记为n,则聚合后释放的能量为m*r*n(Mars单位),新产生的珠子的头标记为m, 尾标记为n。 
    需要时,Mars人就用吸盘夹住相邻的两颗珠子,通过聚合得到能量,直到项链上只剩下一颗珠子为止。显然,不同的聚合顺序得到的总能量是不同的,请你设计一个聚合顺序,使一串项链释放出的总能量最大。 
    例如:设N=4,4颗珠子的头标记与尾标记依次为(2,3) (3,5) (5,10) (10,2)。我们用记号◎表示两颗珠子的聚合操作,(j◎k)表示第j,k两颗珠子聚合后所释放的能量。则第4、1两颗珠子聚合后释放的能量为: 
    (4◎1)=10*2*3=60。 
    这一串项链可以得到最优值的一个聚合顺序所释放的总能量为 
    ((4◎1)◎2)◎3)=10*2*3+10*3*5+10*5*10=710。

    输入

    第一行是一个正整数N(4≤N≤100),表示项链上珠子的个数。第二行 是N个用空格隔开的正整数,所有的数均不超过1000。第i个数为第i颗珠子的头标记(1≤i≤N),当i〈N时,第i颗珠子的尾标记应该等于第i+1颗 珠子的头标记。第N颗珠子的尾标记应该等于第1颗珠子的头标记。 
    至于珠子的顺序,你可以这样确定:将项链放到桌面上,不要出现交叉,随意指定第一颗珠子,然后按顺时针方向确定其他珠子的顺序。

    输出

    只有一行,是一个正整数E(E≤2.1*10^9),为一个最优聚合顺序所释放的总能量

    样例输入
    4
    2  3  5  10
     
     1 #include<cstdio>
     2 #include<iostream>
     3 #define M 210
     4 using namespace std;
     5 int a[M],f[M][M];
     6 int main()
     7 {
     8     int n;
     9     scanf("%d",&n);
    10     for(int i=1;i<=n;i++)
    11     {
    12         scanf("%d",&a[i]);
    13         a[i+n]=a[i];
    14     }
    15     for(int len=1;len<=n-1;len++)
    16       for(int i=1;i<=2*n-len;i++)
    17       {
    18           int j=i+len;
    19           for(int k=i;k<j;k++)
    20             f[i][j]=max(f[i][j],f[i][k]+f[k+1][j]+a[i]*a[k+1]*a[j+1]);
    21       }
    22     int ans=0;
    23     for(int i=1;i<=n;i++)
    24       ans=max(ans,f[i][i+n-1]);
    25     printf("%d",ans);
    26     return 0;
    27 } 
    
    
    


    问题 O: 剩下的树

    时间限制: 1Sec 内存限制: 32MB 提交: 12 解决: 6

    
    
    题目描述

    有一个长度为整数L(1<=L<=10000)的马路,可以想象成数轴上长度为L的一个线段,起点是坐标原点,在每个整数坐标点有一棵树,即在0,1,2,...,L共L+1个位置上有L+1棵树。
        现在要移走一些树,移走的树的区间用一对数字表示,如 100 200表示移走从100到200之间(包括端点)所有的树。
        可能有M(1<=M<=100)个区间,区间之间可能有重叠。现在要求移走所有区间的树之后剩下的树的个数。

    输入

    两个整数L(1<=L<=10000)和M(1<=M<=100)。
        接下来有M组整数,每组有一对数字。

    输出

     可能有多组输入数据,对于每组输入数据,输出一个数,表示移走所有区间的树之后剩下的树的个数。

    样例输入
    4 2
    1 2
    0 2
    11 2
    1 5
    4 7
    0 0
    
    
     1 #include<cstdio>
     2 #include<cstring>//memset头文件
     3 const int maxn = 100010;
     4 int main() {
     5     int tree[maxn];
     6     int L, M, begin, end;
     7     int i, j;
     8     while (scanf("%d %d", &L, &M) != EOF) {
     9         if (L) {
    10             memset(tree, 0, sizeof(tree));
    11             for (i = 1; i <= M; i++) {
    12                 scanf("%d %d", &begin, &end);
    13                 for (j = begin; j <= end; j++)
    14                     tree[j] = 1;
    15             }
    16             for (i = j = 0; i <= L; i++) {
    17                 if (tree[i] == 0)
    18                     j++;
    19             }
    20             printf("%d
    ", j);
    21         }
    22     }
    23     return 0;
    24 }
    
    

    问题 P: P1019

    时间限制: 0Sec 内存限制: 128MB 提交: 13 解决: 6

    题目描述
          给出2个序列A={a[1],a[2],…,a[n]},B={b[1],b[2],…,b[n]},从A、B中各选出n个元素进行一一配对(可以不按照原来在序列中的顺序),并使得所有配对元素差的绝对值之和最大。
    输入
    输入的第1行为1个整数n 第2行包含n个整数,题目中的A序列。  第3行包含n个整数,题目中的B序列。 
    输出
    一个数,最大配对
    样例输入
    4
    2 5 6 3
    1 4 6 7
    
    
     1 #include<iostream>
     2 #include<cstdio>
     3 #include<algorithm>
     4 using namespace std;
     5 int a[10000],b[10000];
     6 int n;
     7 int main()
     8 {
     9     while(scanf("%d",&n)==1)
    10     {
    11         for(int i=0;i<n;i++) scanf("%d",&a[i]);sort(a,a+n);
    12         for(int i=0;i<n;i++) scanf("%d",&b[i]);sort(b,b+n);
    13         int cnt=0;
    14         for(int i=0,j=n-1;i<n;i++,j--)
    15         {
    16             cnt+=a[i]-b[j]>0?a[i]-b[j]:b[j]-a[i];
    17         }
    18         printf("%d
    ",cnt);
    19     }
    20     return 0;
    21 }
    22 
    23  
    
    

    问题 Q: 倒数第二

    时间限制: 1Sec 内存限制: 128MB 提交: 10 解决: 7

    题目描述

    有人说倒数第一是毫无压力的,因为没人任何压力而言,但反而倒数第二是提心吊胆的,因为担心倒数第一有一天考试的时候不来,自己沦为倒数第一(^_^)

    这道题就是求n个成绩(整数)中倒数第二小的数。
    每一个整数都独立看成一个数,比如,有三个数分别是2,2,5,
    那么,第二小的数就是2。

    输入

    输入包含多组测试数据。
    输入的第一行是一个整数C,表示有C组测试数据;
    每组测试数据的第一行是一个整数n,表示本组测试数据有n个整(2<=n<=10),  
    接着一行是 n个整数 (每个数均小于100);

    输出

    请为每组测试数据输出第二小的整数,每组输出占一行。

    样例输入
    2 
    2 
    1 2 
    3 
    1 1 3
     
     1 #include <iostream>
     2 #include <stdlib.h>
     3 using namespace std;
     4 
     5 int cmp(const void *x,const void *y)
     6 {
     7     return (*(int*)x - *(int*)y);
     8 }
     9 
    10 int main()
    11 {
    12     int c;
    13 
    14     cin >> c;
    15     while(c--)
    16     {
    17         int t,i,a[15];
    18         cin >> t;
    19         for(i = 0;i<t;i++)
    20         cin >> a[i];
    21         qsort(a,t,sizeof(int),cmp);
    22         cout << a[1] << endl;;
    23     }
    24 
    25     return 0;
    26 }
    
    
    
     
  • 相关阅读:
    Java——字符串操作
    算法——Java实现队列
    算法——Java实现栈
    算法——线性表之链式存储结构
    算法——线性表之顺序存储结构
    Java——单双引号的区别
    Hystrix源码解析
    Eureka源码探索(一)-客户端服务端的启动和负载均衡
    dubbo源码研究(一)
    dubbo-springboot入门级demo
  • 原文地址:https://www.cnblogs.com/dgwblog/p/9193676.html
Copyright © 2011-2022 走看看