目录
A(Yes-Yes?)
题面翻译
给定
t
t
t 个字符串,请判定这些字符串是否分别是
YesYesYesYes
…
\texttt{YesYesYesYes\dots}
YesYesYesYes… 的子串。是则输出 YES
,否则输出 NO
(YES
和 NO
大小写不定)。
Translated by @JYqwq
样例 #1
样例输入 #1
12
YES
esYes
codeforces
es
se
YesY
esYesYesYesYesYesYe
seY
Yess
sY
o
Yes
样例输出 #1
NO
YES
NO
YES
NO
YES
YES
NO
NO
YES
NO
YES
题目分析
众所不一定周知,有个函数,叫做find()
。其作用就是在某个字符串中寻找其子串。例如x.find(y)!=string::npos
,这个表示在字符串
x
x
x 中寻找
y
y
y,且结果存在于
x
x
x 中,即
y
y
y 为
x
x
x 的子串。那么,我们只需要判断一下是不是
Y
e
s
Y
e
s
Y
e
s
.
.
.
YesYesYes...
YesYesYes... 的子串即可。
正解代码
#include<bits/stdc++.h>
using namespace std;
int t;
string s="YesYesYesYesYesYesYesYesYesYesYesYesYesYesYesYesYesYesYesYes";
int main()
{
//freopen("A.in","r",stdin);
//freopen("A.out","w",stdout);
cin>>t;
while(t--)
{
string a;
cin>>a;
if(s.find(a)!=string::npos)
{
cout<<"YES\n";
}
else
{
cout<<"NO\n";
}
}
}
B(Lost Permutation)
题面翻译
共 t t t 组输入。
对于每组输入,第一行是 m , s m,s m,s,第二行是 b 1 , b 2 , … , b m b_1,b_2,\dots,b_m b1,b2,…,bm。
已知原数组
a
1
,
a
2
,
…
,
a
n
a_1,a_2,\dots,a_n
a1,a2,…,an 是
1
∼
n
1\sim n
1∼n 的一个排列。现在去掉的一些数,变成了
b
1
,
b
2
,
…
,
b
m
b_1,b_2,\dots,b_m
b1,b2,…,bm,去掉的数字的和为
s
s
s。问能否求出一个
a
a
a(能则 YES
,否则 NO
,大小写不敏感)。
样例 #1
样例输入 #1
5
3 13
3 1 4
1 1
1
3 3
1 4 2
2 1
4 3
5 6
1 2 3 4 5
样例输出 #1
YES
NO
YES
NO
YES
题目分析
由于 b b b 中最大的数一定在 a a a 中出现,所以这个排列最小的总和为 b b b 中所有元素之和。然后,与 s s s 进行比较即可。
正解代码
#include<bits/stdc++.h>
using namespace std;
int t;
int m,s;
int a[100000];
int main()
{
//freopen("B.in","r",stdin);
//freopen("B.out","w",stdout);
cin>>t;
while(t--)
{
int maxx=0;
int sum=0;
cin>>m>>s;
for(int i=1;i<=m;i++)
{
cin>>a[i];
sum+=a[i];
maxx=max(maxx,a[i]);
}
int ans=(1+maxx)*maxx/2-sum;
if(ans>s)
{
cout<<"NO\n";
}
else
{
bool bo=0;
int k=maxx+1;
while(ans<=s)
{
if(ans==s)
{
cout<<"YES\n";
bo=1;
break;
}
else
{
ans+=k;
k++;
}
}
if(bo==0)
{
cout<<"NO\n";
}
}
}
return 0;
}
C(Thermostat)
题面翻译
共 t t t 组输入。
对于每组输入,有五个整数 l , r , x , a , b l,r,x,a,b l,r,x,a,b。
对于一个 p p p 的操作,可以从 p p p 变成 q q q,但是要保证 ∣ p − q ∣ ≥ x |p-q|\ge x ∣p−q∣≥x 且 l ≤ q ≤ r l\le q\le r l≤q≤r。
问从
a
a
a 到
b
b
b 需要的最少操作数,若不能到
b
b
b 输出 -1
(题目保证
l
≤
a
,
b
≤
r
l\le a,b \le r
l≤a,b≤r)。
Translated by @JYqwq
样例 #1
样例输入 #1
10
3 5 6
3 3
0 15 5
4 5
0 10 5
3 7
3 5 6
3 4
-10 10 11
-5 6
-3 3 4
1 0
-5 10 8
9 2
1 5 1
2 5
-1 4 3
0 2
-6 3 6
-1 -4
样例输出 #1
0
2
3
-1
1
-1
3
1
3
-1
题目分析
首先,有三种需要特判的情况:
- 当
a
=
b
a=b
a=b 时:
无需操作,答案为 0 0 0。 - 当
∣
a
−
b
∣
≥
x
|a-b|≥x
∣a−b∣≥x 时:
一次操作即可,答案为 1 1 1。 - 当
∣
l
−
b
∣
<
x
|l-b|<x
∣l−b∣<x 并且
∣
r
−
b
∣
<
x
|r-b|<x
∣r−b∣<x 时:
不可能成功,答案为 − 1 -1 −1。
然后,我们就需要考虑操作的问题了。为了能使操作进行, ∣ a − b ∣ |a-b| ∣a−b∣ 的值要尽量的大。所以,我们不妨先把 a a a 的值移到边界 l , r l,r l,r 上,判断此时能否触发条件进行操作,将其值调整到 b b b 上,如果能,答案为 2 2 2;否则跳到另一端的边界上,再次判断能否在这端的边界将其值调整为 b b b,如果能,答案为 3 3 3;否则不更新答案。
最后,如果如果怎么调整都无法满足条件,则答案为 − 1 -1 −1。
正解代码
#include<bits/stdc++.h>
#define int long long
using namespace std;
int t;
int l,r;
int x,a,b;
signed main()
{
//freopen("C.in","r",stdin);
//freopen("C.out","w",stdout);
cin>>t;
while(t--)
{
int k=1e5;
cin>>l>>r>>x>>a>>b;
if(a==b)
{
cout<<0<<"\n";
continue;
}
if(abs(a-b)>=x)
{
cout<<1<<"\n";
continue;
}
if(abs(l-b)<x&&abs(r-b)<x)
{
cout<<-1<<"\n";
continue;
}
if(abs(l-a)>=x)
{
if(abs(l-b)>=x)
{
k=2;
}
else{
k=3;
}
}
if(abs(r-a)>=x)
{
if(abs(r-b)>=x)
{
k=2;
}
else
{
k=k<3?k:3;
}
}
if(k>3)
{
cout<<-1<<"\n";
}
else
{
cout<<k<<'\n';
}
}
return 0;
}
D(Make It Round)
题面翻译
给定 n n n 和 m m m, 我们可以把 n n n 变为 n ⋅ k ( 1 ≤ k ≤ m , k ∈ N ∗ ) n\cdot k(1\leq k\leq m,k∈N^{*}) n⋅k(1≤k≤m,k∈N∗), 请输出末尾 0 0 0 的个数最多的 n ⋅ k n\cdot k n⋅k。
- 例如, 481000 481000 481000 比 1000010 1000010 1000010 末尾 0 0 0 的个数更多。
- 如果有多个末尾 0 0 0 个数最多的 n ⋅ k n\cdot k n⋅k, 则输出其中最大的一个。
- 如果不存在末尾 0 0 0 个数更多的 n ⋅ k n\cdot k n⋅k, 则输出 n ⋅ m n\cdot m n⋅m。
输入格式
第一行输入一个整数
t
(
1
≤
t
≤
1
0
4
)
t\ (1\leq t \leq 10^4)
t (1≤t≤104), 表示数据组数。
之后的
t
t
t 行,每行包含两个整数
n
n
n,
m
(
1
≤
n
,
m
≤
1
0
9
)
m\ (1\leq n,m \leq 10^9)
m (1≤n,m≤109)。
输出格式
对于每组数据,输出末尾 0 0 0 的个数最多的 n ⋅ k ( 1 ≤ k ≤ m , k ∈ N ∗ ) n\cdot k\ (1\leq k\leq m,k∈N^{*}) n⋅k (1≤k≤m,k∈N∗)。
如果有多个末尾 0 0 0 个数最多的 n ⋅ k n\cdot k n⋅k, 则输出其中最大的一个。
如果不存在末尾 0 0 0 个数更多的 n ⋅ k n\cdot k n⋅k, 则输出 n ⋅ m n\cdot m n⋅m。
样例解释
在第一组数据中 n = 6 , m = 11 n=6,m=11 n=6,m=11, 我们无法得到一个末尾有两个 0 0 0 的数,因此我们令 k = 10 k=10 k=10, 输出 6 ⋅ 10 = 60 6\cdot 10=60 6⋅10=60。(它的末尾有 1 1 1 个 0 0 0, 且它比 30 30 30 更大)
在第三组数据中 n = 13 , m = 5 n=13,m=5 n=13,m=5, 所有可能的 n ⋅ k n\cdot k n⋅k 末尾都没有 0 0 0, 因此我们输出 n ⋅ m = 65 n\cdot m=65 n⋅m=65。
样例 #1
样例输入 #1
10
6 11
5 43
13 5
4 16
10050 12345
2 6
4 30
25 10
2 81
1 7
样例输出 #1
60
200
65
60
120600000
10
100
200
100
7
题目分析
背过九九乘法表的都知道 10 = 2 × 5 10=2×5 10=2×5,所以某个数字有多少个 0 0 0 就相当于有多少个 2 × 5 2×5 2×5 啦。我们设剩下的乘积为 x x x,则我们只需要在 [ 1 , m ] [1,m] [1,m] 中找到 x x x 的最大的倍数,也就是 ⌊ m / x ⌋ × x ⌊ m/x⌋×x ⌊m/x⌋×x(不会打分数线),然后乘以原来的那个数即可。
正解代码
#include<bits/stdc++.h>
#define int long long
using namespace std;
int t;
int n,m;
signed main()
{
//freopen("D.in","r",stdin);
//freopen("D.out","w",stdout);
cin>>t;
while(t--)
{
cin>>n>>m;
for(int i=18;i>=0;i--)
{
int s=n;
int x=i,y=i;
int sum=1;
while(s%2==0&&s>0)
{
s/=2;
x--;
}
while(s%5==0&&s>0)
{
s/=5;
y--;
}
while(x>0)
{
sum*=2;
x--;
}
while(y>0)
{
sum*=5;
y--;
}
if(sum<=m)
{
int X=m/sum*sum;
cout<<n*X<<endl;
break;
}
}
}
return 0;
}