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组整数,每组有一对数字。
可能有多组输入数据,对于每组输入数据,输出一个数,表示移走所有区间的树之后剩下的树的个数。
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
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 }