目录
一、小美摆积木
题目描述:
小美想要为小团摆一行积木,每个积木上都有一个0-9的数字。现在已经摆好了 n 块积木,小美可以把其中一块积木替换成任意一块积木(也可以不替换),使得积木看起来更符合小美的审美。请你帮小美看看,替换后最好看的积木是什么样的。
摆好后的积木上面的数字,从左到右会形成一个数字串(由数字组成的字符串)。小美会根据这个数字串来评判积木的好看程度,小美有两条审美标准:
①回文数字串相比于非回文数字串更符合小美的审美。例如:12321、2332是回文数字串,而12212、2121不是回文数字串。
②数字串形成的数字更小更好看。例如:1312比1313更好看,0102比1102更好看。
小美会按照她的审美标准来判断两个数字串哪个更好看,即先按照审美标准①判断,若无法判断再按审美标准②判断。
输入描述
第一行一个数 T,表示一共有 T 组测试数据。(1 ≤ T ≤ 100)。
接下来 T 组数据,每组数据两行,
第一行一个数 n,表示有 n 块积木。(1 ≤ n ≤ 20000)。
第二行 n 个数字,第 i 块积木上的数字是 si。(si是0-9的数字)。
输出描述
每组数据输出一行,表示最终摆好的积木形成的数字串。
样例输入
2
5
00011
5
11210
样例输出
00001
01210
提示
第一组数据:
替换一块积木,无法使数字串变成回文数字串,因此只能数字串形成的数字最小。
第二组数据:
可以把第一块积木1换成0,也可以把第五块积木0换成1,从而使得积木是回文积木。又想要积木字典序最小,所以把第一块积木1替换成0。
#include <stdio.h>
#include <stdlib.h>
char min(char a, char b){
return a>b?b:a;
}
int main(){
int t, n;
char str[20005];
scanf("%d", &t);
while(t--){
scanf("%d", &n);
scanf("%s", str);
int sum = 0;
for(int i = 0; i < n/2; i++){
if(str[i] != str[n-1-i]){
sum ++ ;
}
}
if(sum == 0){
if(n % 2 == 0){
printf("%s\n", str);
}else{
str[n / 2 + 1] = '0';
printf("%s\n", str);
}
}else if(sum == 1){
for(int i = 0; i < n/2; i++){
if(str[i] != str[n-1-i]){
str[i] = min(str[i], str[n-1-i]);
str[n-1-i] = str[i];
break;
}
}
printf("%s\n", str);
}else{
for(int i = 0; i < n ; i++){
if(str[i] != '0'){
str[i] ='0';
break;
}
}
printf("%s\n", str);
}
}
}
二、小美斗龙
题目描述:
小美得到了一款游戏——斗龙。小美拥有两个技能,每个技能都能秒杀掉一条龙,但是要付出相应的MP值,第一个技能需要c1点MP值,第二个技能需要c2点MP值。只要MP足够,小美可以使用无限次技能。
小美即将遇到 n 条龙,如果不使用技能,她和第 i 条龙的战斗结果是T或者F,而如果使用任何一个技能战斗结果都是T。T表示小美成功打败龙,而F表示小美被龙打败。如果小美被龙连续打败三次,那小美就会输掉游戏。请你帮忙计算小美最少需要多少点 MP才能通关。
输入描述
第一行三个数 n, c1, c2。(1 ≤ n ≤ 100000,1 ≤ c1, c2 ≤ 1000000000)。
第二行 n 个字符,第 i 个字符 si 代表小美与第 i 场战斗的结果。si 是 T 代表小美打败龙,si 是 F 代表小美被龙打败。
输出描述
输出一个数,代表小美最少需要的MP值。
样例输入
10 7 3
FTFFFTFFFF
样例输出
6
提示
小美可以在第3场战斗、第8场战斗中使用第二个技能,需要耗费3×2=6点MP。
#include <stdio.h>
long long int min(long long int a, long long int b){
return a>b?b:a;
}
int main(){
int n;
long long int c1, c2;
scanf("%d", &n);
scanf("%lld%lld", &c1, &c2);
char str[100005];
scanf("%s", str);
int count = 0;
for(int i = 2; i < n; i++){
if(str[i-2] == 'F'&& str[i-1] == 'F' && str[i] =='F'){
count ++;
str[i] = 'T';
}
}
printf("%lld\n", count * min(c1, c2));
return 0;
}
三、小美记数字
小美的记忆力超级棒,小团决定来考一考小美。小团给了小美 n 个数,从左到右排成一行,给了1 分钟让小美记住。然后小团会询问 m 次,每次都问数 x 第一次出现的位置和最后一次出现的位置,若数 x 没出现过,那么回答 0 即可。小美的记忆力好,但是 1 分钟记住这么多数实在是太难了,请你帮帮小美,完成这次不可能的挑战。
输入描述
第一行两个数 n, m。(1 ≤ n, m ≤ 50000)。
第二行 n 个数,第 i 个数是 ai。(1 ≤ ai ≤ 1000000000)。
接下来 m 行,每行一个数 x (1 ≤ x ≤ 1000000000),代表一次询问。
输出描述
输出 m 行,若数 x 出现过,输出数 x 第一次出现的位置和最后一次出现的位置。若数 x 没出现过,输出 0。
样例输入
6 4
2 3 1 2 3 3
1
2
3
4
样例输出
3 3
1 4
2 6
0
提示
1 出现的位置有 3,所以答案为 3 3。
2 出现的位置有 1, 4,所以答案为 1 4。
3 出现的位置有 2, 5, 6,所以答案为 2 6。
4 没有出现过,所以答案为 0。
#include <stdio.h>
#include <stdlib.h>
struct A{
long long int x;
int r, l;
}a[100000005];
int main()
{
int n, m;
long long int x;
scanf("%d %d", &n, &m);
int num = 0;
for(int i = 1; i <= n; i++){
scanf("%lld", &x);
int j;
for(j = 0; j < num; j++){
if(a[j].x == x){
a[j].r = i;
break;
}
}
if(j == num){
a[j].x = x;
a[j].r = i;
a[j].l = i;
num++;
}
}
while(m--){
scanf("%lld", &x);
int j;
for(j = 0; j < num; j++){
if(a[j].x == x){
printf("%d %d\n", a[j].l, a[j].r);
break;
}
}
if(j == num){
printf("%d\n", 0);
}
}
return 0;
}
四、小美中奖啦
题目描述:
小美超级幸运,这不今天又双叒叕中奖了!!!主办方给了小美 n 个积分球,从左到右排成一行,第 i 个积分球的积分为 ai 。让小美自行选取其中一段连续的积分球,最多选取k 个。假设小美选取了 [l, r] 这个区间中的积分球,小美获得的积分为al⊕al+1⊕…⊕ar-1⊕ar。例如,小美选取了 [3, 4, 2] 这三个积分球那么小美最终获得的积分为 3⊕4⊕2 = 5。
小美想要获得最多的积分。小美虽然幸运,但是却被这个难题难倒了,请你帮帮小美,帮她获得更多积分。
⊕:异或运算的数学符号。其运算法则相当于不带进位的二进制加法:二进制下用1表示真,0表示假,则异或的运算法则为:0⊕0=0,1⊕0=1,0⊕1=1,1⊕1=0(同为0,异为1),这些法则与加法是相同的,只是不带进位,所以异或常被认作不进位加法。例如:3⊕5=(011)2 ⊕ (101) 2 = (110) 2 = 6。
异或在C语言中表示为^。
输入描述
第一行两个数 n, k。(1 ≤ n, k ≤ 100000)。
第二行 n 个数,第 i 个数是 ai。(0 ≤ ai ≤ 1000000000)。
输出描述
输出一个数,代表小美能够获得的最多积分。
样例输入
3 2
1 2 4
样例输出
6
提示
小美有如下几种选择。
①选取区间 [1, 1] 中的积分球,获得积分为 1。
②选取区间 [1, 2] 中的积分球,获得积分为 3。
③选取区间 [2, 2] 中的积分球,获得积分为 2。
④选取区间 [2, 3] 中的积分球,获得积分为 6。
⑤选取区间 [3, 3] 中的积分球,获得积分为 4。
#include <stdio.h>
#include <stdlib.h>
long long int max(long long int a, long long int b){
return a>b? a :b;
}
int main()
{
int n, k;
long long int a[100005], Max = 0;
scanf("%d %d", &n, &k);
for(int i = 0; i < n; i++){
scanf("%lld", &a[i]);
}
for(int i = 0; i < n; i++){
for(int j = 0; j < k; j++){
long long int temp = a[i];
if(j == 0){
Max = max(Max, a[i+j]);
}else{
if(i + j < n){
Max = max(Max, temp^a[i+j]);
}
}
}
}
printf("%lld\n", Max);
return 0;
}
五、银杏树
小美负责维护某人民公园内的所有银杏树。
公园里有 n 棵银杏,编号为 1…n,第i棵树的高度为 hi。但是树木太多,她自己一个人肯定无法完成任务,于是她找了一些同学,并将他们分为两组。
为了公平,小美要确定两组的工作量(总爬树高度)一样多,而且小美也要参与工作。于是小美这样安排:自己先选一棵树 x 进行修剪,编号为 [x + 1, n] 的树重新编号为 [x,n - 1],[1,x - 1] 的部分编号不变。对于新的编号,奇数编号的树由一队同学修剪,偶数编号的树由另一队同学修剪。
请帮小美计算,自己选择可以选择修剪哪些树才能让两组同学的工作量(总爬树高度)一样多。并输出方案数。
输入描述
第一行一个正整数 n,表示一共有 n 棵树;
第二行 n 个正整数 hi,第 i 个正整数表示第 i 棵树高度为 hi。
1 ≤ n ≤ 2×105, 1 ≤ hi ≤ 104。
输出描述
如果无论小美怎么选择,都没有一种方案可以使得两组工作量相同,则只输出一行一个数 0。
否则输出两行,第一行输出一个正整数表示小美选择树的方案数,第二行从小到大输出小美可以选择修剪树的编号,每两个编号之间有一个空格。请不要输出行末空格。
样例输入
4
1 4 2 3
样例输出
1
3
#include <stdio.h>
#include <stdlib.h>
int main(){
int n, h[1005];
scanf("%d", &n);
for(int i = 0; i < n ;i++){
scanf("%d", &h[i]);
}
int sum = 0, list[1005];
for(int i = 0; i < n; i++){
int sum1 = 0, sum2 = 0;
for(int j = 0; j < n; j++){
if(j > i){
if(j % 2 == 0){
sum1 += h[j];
}else{
sum2 += h[j];
}
}else if(j < i){
if(j % 2 == 1){
sum1 += h[j];
}else{
sum2 += h[j];
}
}
// printf("%d %d\n", sum1, sum2);
}
if(sum1 == sum2){
list[sum] = i + 1;
sum ++;
}
}
if(sum == 0){
printf("0");
return 0;
}
printf("%d\n", sum);
for(int i = 0; i < sum; i++){
printf("%d ", list[i]);
}
return 0;
}