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("\n");
    }
    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组整数,每组有一对数字。

输出

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

扫描二维码关注公众号,回复: 1627470 查看本文章
样例输入
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\n", 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\n",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 }
 
      
     
 

猜你喜欢

转载自www.cnblogs.com/dgwblog/p/9193676.html