今天主要在刷菜鸟杯的模拟题,拓展了一下自己的思维。以下是今天碰到的重点题目。
1.会长喝饮料
问题:给定一个序列代表一排嘤料瓶,0代表是个空瓶,1代表是非空瓶,要求把这一排嘤料瓶变成连续一段空瓶在前,接着一段连续非空瓶在后,(可以全是空瓶,或者全是非空瓶,详见提示),把空瓶变成非空瓶时间是1秒,同样的把非空瓶变成空瓶的时间也是1秒。
会长渴的一匹已经说不出话了,你能帮帮会长在最快的时间内喝到嘤料吗?
格式
输入格式
第一行一个正整数T代表测试数据组数(1<=T<=100)
接下来每组测试数据包含两行
第一行一个正整数N表示一排嘤料的瓶数(1<=N<=2*105)
第二行一个01序列代表给定一排嘤料瓶的状态(0代表是个空瓶,1代表是非空瓶)
输出格式
每组测试数据输出一个整数代表会长喝到嘤料需要的时间。
样例
样例输入 Copy
3
5
00001
8
01100111
6
010111
样例输出 Copy
0
2
1
提示
第一组数据00001,已经满足阿拉丁的要求所以不需要等待就能喝到嘤料!
第二组数据01100111,可以将第二瓶和第三瓶变成0(空瓶),序列变成00000111满足阿拉丁的要求,花费2秒喝到嘤料!
第三组数据010111,可以将第三瓶变成1(非空瓶),序列变成011111满足阿拉丁的要求,花费1秒喝到嘤料!
思路分析:这道题的思路就是,用两个数组,一个存0的个数,一个存1的个数,并且存1的时候,是顺序赋值,查找当前位置之前的1有多少个,存0的时候是逆序赋值,查找当前位置之后的0有多少个,把每个位置对应的0和1的个数加起来存到另一个数组中,最后输出最小的即可。
代码实现:
#include<stdio.h>
#include<string.h>
char a[200001];
int b[200001],c[200001];
int main()
{ int t,n,i,j,min;
scanf("%d",&t);
while(t--)
{
scanf("%d",&n);
getchar();
scanf("%s",a);
for(i=1;i<=n;i++)
if(a[i-1]=='1')
b[i]=b[i-1]+1;
else
b[i]=b[i-1];
for(i=n-1;i>=0;i--)
if(a[i]=='0')
c[i]=c[i+1]+1;
else c[i]=c[i+1];
min=b[0]+c[0];
for(i=1;i<=n;i++)
if(min>b[i]+c[i])
min=b[i]+c[i];
printf("%d\n",min);
for(j=0;j<=n;j++)a[j]=b[j]=c[j]=0;
}
return 0;
}
2.
破译wifi密码
描述
wifi名称由两个大写的字母 zm 和 sz 组成,第一个字母 zm 用于破译字母图形密码,可以根据样例进行破译;第二个字母 sz 用于破译数字密码,数字密码是看字母图形密码中含有几个 sz 字母。
格式
输入格式
多组输入,多组输入,多组输入(重要的事说三遍)
第一行输入两个大写字母 zm 和 sz('A'<=zm,sz<='Z') ,表示需要破译的wifi名称。
输出格式
先输出字母密码(每一行的最后一个字母后面都是没有空格的)
再输出数字密码
样例
样例输入
CB
DF
AA
BB
ED
样例输出
CBABC
CBC
C
CBC
CBABC
6
DCBABCD
DCBCD
DCD
D
DCD
DCBCD
DCBABCD
0
A
1
BAB
B
BAB
5
EDCBABCDE
EDCBCDE
EDCDE
EDE
E
EDE
EDCDE
EDCBCDE
EDCBABCDE
14
提示
字母密码根据样例找规律得到。
样例1:字母图形密码中含有6个字母B,所以数字密码为6.
样例2:字母图形密码中没有字母F,所以数字密码是0.
样例3:字母图形密码中含有1个字母A,所以数字密码为1.
样例4:字母图形密码中含有5个字母B,所以数字密码为5.
样例5:字母图形密码中含有14个字母D,所以数字密码为14.
思路分析:这道题的主要就是把输出分成了两个部分,上部分为zm-’A+1行,下部分为上部分的行数-1。
代码实现:
#include<stdio.h>
int main()
{ int n,i,j,sum;
char zm,sz;
while(~scanf("%c%c",&zm,&sz))
{n=zm-'A'+1;sum=0;
for(i=1;i<=n;i++)
{ for(j=1;j<i;j++) //输出空格
printf(" ");
for(j=n;j>=i;j--) //逆序输出zm到字母A
{printf("%c",j+'A'-1);
if(j+'A'-1==sz)sum++;
}
for(j=i+1;j<=n;j++)//从B开始正序输出到字母zm
{printf("%c",j+'A'-1);if(j+'A'-1==sz)sum++;}
printf("\n");
}
for(i=n-1;i>=1;i--)
{
for(j=1;j<i;j++)
printf(" ");
for(j=n;j>=i;j--)
{printf("%c",j+'A'-1);if(j+'A'-1==sz)sum++;}
for(j=i+1;j<=n;j++)
{printf("%c",j+'A'-1);if(j+'A'-1==sz)sum++;}
printf("\n");
}
printf("%d\n",sum);
getchar();
}
return 0;
}
3. LYY喜欢数字
描述
LYY非常喜欢研究数字.
他喜欢5和9,但不喜欢1.
现在他想知道0到10的n次方以内有多少个数满足以下条件
1.对于这个数的每一位不存在1
2.对于这个数的每一位至少存在一个5
3.对于这个数的每一位至少存在一个9
例如:当n等于2时,0到100中只有59和95符合条件,所以输出2。
输入格式
输入一个n,1<=n<=19
输出格式
统计有多少个LYY喜欢的数存在.
样例
样例输入 Copy
2
样例输出 Copy
2
提示
对于输入2,0到100中有59和95符合条件,所以输出2
思路分析:我们只要考虑n-1位的情况即可,因为若n=4的时候,最大值为pow(10,4)=10000,第一位为1直接就排除了。
每个位置上的可以放0~9也就是10个数字,就有pow(10,n)种情况,如果不考虑1的话,就是pow(9,n),没有1且没有5的情况有pow(8,n),没有1且没有9的情况有pow(8,n),用没有1的情况-没有1且没有5的情况-没有1且没有9的情况=没有1且必有5且必有9的情况,但是特别要注意,会出现重复减去的情况,例如只要是不由1,5,9组成的数,既会被第二种情况减去也会被第三种情况减去,因此还需要加上一个pow(7,n)
代码实现:
#include<stdio.h>
long long i,j,sum=0,num;
int main()
{ int n;
scanf("%d",&n);
num=1;
for(i=1;i<=n;i++)
num*=9;
sum+=num;
num=1;
for(i=1;i<=n;i++)
num*=8;
sum-=num;
sum-=num;
num=1;
for(i=1;i<=n;i++)
num*=7;
sum+=num;
printf("%lld",sum);
return 0;
}