A. k-rounding:
题意:
给你一个n和一个k,让你求出最小的n的倍数,并且这个数有k个尾0。比如100有2个尾0。
POINT:
求n和1ek的公倍数。
#include <iostream>
#include <cmath>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <algorithm>
#include <string>
typedef long long LL;
using namespace std;
LL gcd(LL a, LL b)
{
return b==0?a:gcd(b,a%b);
}
int main()
{
LL a;
scanf("%lld",&a);
LL k;
scanf("%lld",&k);
if(k==0)
{
printf("%lld\n",a);
return 0;
}
LL b=(LL)pow(10,k);
if(a<b) swap(a, b);
LL c=gcd(a,b);
printf("%lld\n",a*b/c);
}
B. Which floor?
题意:
1-n个房间依次从下到上分布在楼层中,每个楼层都有相同数量的房间,现在给你m个房间所在的楼层。房间标号和所在楼层。
让你判断第n号房间在第几层。如果答案有多种,输出-1。
point:
因为n最大就100,暴力遍历每层楼的房间数,和m个数据进行比较,都成功说明这个房间数是可能的。算出n在第几层。
如果答案不一,输出-1。注意不要以为每层楼的房间数不一样就可以输出-1,这不一定。
#include <iostream>
#include <cmath>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <algorithm>
#include <string>
typedef long long LL;
using namespace std;
struct node
{
int k,f;
}a[111];
int main()
{
int n,m;
scanf("%d %d",&n,&m);
for(int i=1;i<=m;i++)
{
scanf("%d %d",&a[i].k,&a[i].f);
}
int ans=0;
int j;
for(int i=1;i<=100;i++)
{
for(j=1;j<=m;j++)
{
int k=a[j].k;
int f=a[j].f;
int tobe=k/i;
if(k%i!=0) tobe++;
if(tobe!=f)
{
break;
}
}
if(j==m+1)
{
int tobe=n/i;
if(n%i!=0) tobe++;
if(ans!=tobe&&ans!=0)
{
ans=-1;
break;
}
ans=tobe;
}
}
printf("%d\n",ans);
}
C. Did you mean...
题意:
给你一串字母串,让你分割它们。Formally, a word is typed with a typo if there is a block of not less that three consonants in a row, and there are at least two different letters in this block.
如果一串中不是所有字母都相同且数量不小于3,即(数量不小于3的子串中含有2个字母以上),则要被分离。
以上条件只对辅音字母有效。
#include <iostream>
#include <cmath>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <algorithm>
#include <string>
typedef long long LL;
using namespace std;
int main()
{
char a[3333];
scanf("%s",a);
int l=(int)strlen(a);
int f=0;
for(int i=0;i<l;i++)
{
if(a[i]!='a'&&a[i]!='e'&&a[i]!='i'&&a[i]!='o'&&a[i]!='u')
{
f++;
if(f==3)
{
if(a[i]==a[i-1]&&a[i-1]==a[i-2])
f--;
else
{
printf(" ");
f=1;
}
}
}
else
f=0;
printf("%c",a[i]);
}
printf("\n");
}
D. Polycarp's phone book
题意:
给你n个长度必定为9的手机号。在手机里寻找手机号时,只要你输出一个手机号里的子串,就能显示这个手机号。
比如123456789和789123456,你输入123456,这两个手机号就被同时显示。
现在要让你求出对于每个手机号,他的最短个人子串是什么,即输入这个子串,只有他能被显示,且要最短。
POINT:
对于每个手机号,从s+0到s+8都存入字典树,如果一个位置有对应两个手机号,那么这个位置不能用。
再对于每个手机号,从s+0到s+8询问,找到一个位置可以用的说明就是他的个人子串。是不是最短只要在找的时候比较一下就行了。
#include <iostream>
#include <cmath>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <algorithm>
#include <string>
typedef long long LL;
using namespace std;
const int maxn = 777777;
int tree[maxn][10];
int flag[maxn];
int sz;
void init()
{
sz=0;
memset(tree,0,sizeof tree);
}
void build(char s[],int k)
{
int u=0;
int l=(int)strlen(s);
for(int i=0;i<l;i++)
{
int now=s[i]-'0';
if(tree[u][now]==0)
{
tree[u][now]=++sz;
while(sz>maxn)
printf("1");
u=tree[u][now];
flag[u]=k;
}
else
{
u=tree[u][now];
if(flag[u]!=k)
flag[u]=0;
}
}
}
int ans[11];
int minl;
void query(char s[],int k)
{
int u=0;
int l=(int)strlen(s);
for(int i=0;i<l;i++)
{
int now=s[i]-'0';
u=tree[u][now];
if(flag[u]==k)
{
if(minl>i+1)
{
minl=i+1;
for(int j=1;j<=minl;j++)
{
ans[j]=s[j-1]-'0';
}
break;
}
}
}
}
int main()
{
init();
char s[70003][10];
int n;
scanf("%d",&n);
for(int i=1;i<=n;i++)
{
scanf("%s",s[i]);
for(int j=0;j<=8;j++)
{
build(s[i]+j,i);
}
}
for(int i=1;i<=n;i++)
{
minl=10;
for(int j=0;j<=8;j++)
{
query(s[i]+j,i);
}
for(int j=1;j<=minl;j++)
{
printf("%d",ans[j]);
}
printf("\n");
}
}