文章目录
Problem C: 独爱’0’的LSP
Description
LSP十分热爱数学,他特别喜欢’0’这个数字。现在给你一个数字N,LSP想知道一个可以整除N的最小非负整数,并且N至少有K个或者更多个0结尾。如果N为75,K为4,则结果为75*400=30000。
Input
第一行包含一个整数T(0<=T<=100),这意味着T测试用例。每个测试用例包含两个整数N和K。(1<=N<=1e9,0<=K<=8)
Output
对于每个测试用例,打印一行答案。
Sample Input
2
75 4
10000 1
Sample Output
30000
10000
这道题很坑,在于我们没有找到题目的原理,想找到一个可以整除n的最小非负整数,并且有至少k个0结尾。
其实这道题是在让求n和10^k的最小公倍数。因为最小公倍数一定至少有k个0.
利用辗转相除法求出最大公因数(较大数除以较小数),再用两个数的乘积除以最大公因数。
注意这道题都要设置成long long 类型,否则会有错误(原来是这里的锅)。
#include<bits/stdc++.h>
using namespace std;
long long gcd(long long a,long long b)
{
if(b==0) return a;
return gcd(b,a%b);
}
int main()
{
long long t,n,k,kk=1;
long long temp,ans;
scanf("%lld",&t);
while(t--)
{
kk=1;
scanf("%lld%lld",&n,&k);
for(int i=0;i<k;i++)
kk*=10;
if(n<kk)
{
temp=kk;
kk=n;
n=temp;
}
ans=n*kk/gcd(n,kk);
printf("%lld\n",ans);
}
return 0;
}
Problem H: 帮帮小文吧
Description
小文暗恋同校的一个女生好久了!但是他由于比较害羞,连这个女生的名字都不知道。恰巧小文的队友知道这个女生的名字,但是他不会轻易地告诉小文。
他给了小文一个由小写字母组成的字符串S,并让小文把这个字符串所有的子串都挑出来。其中,有一种子串K应当包含了所有的小写字母,在这类子串中,长度最短的就是这个女生的名字。
队友要小文告诉他这个女生名字的长度,他才肯告诉小文这个女生的真正名字(汉字及发音)。
小文学习字符串两年了,面对队友出的题…他还是不会。但是他又非常想知道这个女生的名字,你能帮帮他吗?
PS:大家都知道程序员找个女朋友不容易,帮帮小文吧!
Input
第一行是一个整数 T ,代表有 T 个样例
每个样例包含一个字符串S,长度小于1e6。
Output
一行一个数字,代表名字的长度。如果队友题出错了,没有这种子串K,请输出“-1”。这样队友出于对你的崇拜也会告诉你这个女生的名字哒。
Sample Input
1
ykjygvedtysvyymzfizzwkjamefxjnrnphqwnfhrnbhwjhqcgqnplodeestu
Sample Output
49
这是一道尺取法的题目,因为数据量并不大,可以直接遍历来找是否含义26个字母。用一个变量sum来记录所含的不同字母个数。
注意如果要直接用r-l来表示区间长度的话,我们的区间求和就要用左闭右开的形式。
#include<stdio.h>
#include<string.h>
#include<algorithm>
const int inf=0x3f3f3f3f;
using namespace std;
char arr[1000005];
int f(int l,int r)
{
int ans=0;//含有不同种字母的个数
bool alp[125];//记录是否含有相应的字母
memset(alp,0,sizeof alp);
for(int i=l;i<r;i++)//左闭右开
alp[arr[i]]=1;
for(int i='a';i<='z';i++)
ans+=alp[i];
return ans;
}
int main(void)
{
int t,n,l,r,ans;//组数、字符串长度、左端点、右端点、每次记录的最小长度。
int sum;//字符串中不同英文字母的个数
scanf("%d",&t);
while(t--)
{
ans=inf;
scanf("%s",arr);
n=strlen(arr);
l=0;r=0;
sum=0;
while(true)//双重循环
{
while(r<n&&sum<26)//判断是否到达给出的最后一个数字和选取得区间是否达到s,如果没有,右端点向右移动
{
r++;//向右移动
sum=f(l,r);//更新sum
}
if(sum<26)//判断是否达到了26
break;
ans=min(r-l,ans);//从刚才得到得区间长度和已保存得长度中选最小的
l++;//左端点向右移动
sum=f(l,r);
}
if(ans==inf)//不存在区间和大于s的区间
printf("-1\n");
else//存在
printf("%d\n",ans);
}
return 0;
}
Problem K: 挑剔的MDL
Description
夏天真是一年中最美好的时光!一个叫MDL的女孩正在森林里散步,一片落叶缓缓落在了她的手中。但是MDL很挑剔——如果一片叶子的颜色和种类与她已有的一片叶子的颜色和种类相匹配,她就不会摘。看看MDL一共摘了多少叶子。
Input
有多组输入第一行输入 N ,表示下面有 N 组叶子的颜色与种类。接下来连续 N 行,每行有两个字符串(字符串长度不超过10),分别代表叶子的颜色和种类。
Output
输出单独一行输出MDL摘了多少叶子。
Sample Input
3
aba ab
aba ab
bb aa
Sample Output
2
这道题很简单,但是坑点就是没有注意多组输入,还有每组开始时没有给ans设置初始值0
#include<stdio.h>
#include<string.h>
struct lea
{
char col[15],kin[15];
}lea[10005];
int main(void)
{
int n,ans;
bool flag;//标记叶子是否被捡到过
while(scanf("%d",&n)!=EOF)
{
ans=0;
for(int i=0;i<n;i++)
{
scanf("%s %s",lea[i].col,lea[i].kin);
flag=0; //注意flag的位置
for(int j=0;j<i;j++)
{
if(strcmp(lea[j].col,lea[i].col)==0&&strcmp(lea[i].kin,lea[j].kin)==0)
{
flag=1;
break;
}
}
if(!flag)
ans++;
}
printf("%d\n",ans);
}
return 0;
}