题集链接
Codeforces Round 834
- A. Yes-Yes?
- B. Lost Permutation
- C. Thermostat
A. Yes-Yes?
Example
input
12
YES
esYes
codeforces
es
se
YesY
esYesYesYesYesYesYe
seY
Yess
sY
o
Yes
output
NO
YES
NO
YES
NO
YES
YES
NO
NO
YES
NO
YES
题意&题解:
其实就算问给的字符串是不是多个YES的字串,因为给出的字符串长度已经定了,直接来个 ∣ s t r i n g 1 ∣ > = 50 |string1|>=50 ∣string1∣>=50的多个“YES”来find一下,就可以了!!!
C++
#include <iostream>
#include <algorithm>
#define int long long
using namespace std;
const int N = 2*1e5+10;
string s;
int n;
char ch;
string string1="YesYesYesYesYesYesYesYesYesYesYesYesYesYesYesYesYesYes";
void sove(void){
cin>>s;
if(string1.find(s)!=string::npos)cout<<"YES\n";
else cout<<"NO\n";
}
signed main(void){
int _=1;
cin>>_;
while(_--)sove();
return 0;
}
如果用C,可以按照规律,Y后面一定是e,e后面一定是s,s后面一定是Y,如果出现不是这三个字母的,直接NO
C
#include <stdio.h>
#define end {printf("NO\n");return;};
void solve();
int main(void){
int _=1;scanf("%d\n",&_);
while(_--)solve();
return 0;
}
void solve(){
char s[52];
scanf("%[^\n]",s);getchar();
for(char i=0,next=' ';s[i];i++){
if(next!=' '&&s[i]!=next|| (s[i]!='Y'&&s[i]!='e'&&s[i]!='s')){
end
}
if(s[i]=='Y')next='e';
else if(s[i]=='e')next='s';
else if(s[i]=='s')next='Y';
}
printf("YES\n");
}
B. Lost Permutation
Example
input
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
output
YES
NO
YES
NO
YES
题意:
给你一个长度为 m m m的数组(缺失排列(排列少数字))和 s s s(少掉的数字之和)
让你判断,能不能恰好用 n n n个数字,数组加上这 n n n个数字变成一个新排序,并且 n n n个数字之和等于 s s s,如果可以打印“YES”
否则"NO"
注:排列是指该数组里 1 − n 1-n 1−n的数字恰好出现一次
题解:
因为是排列,而且是添加数字,如果数组里现有的最大数字为 x x x,然后将数组补全为 1 − x 1-x 1−x排列,如果用到的数字之和大于 s s s了,直接NO,否则进行进行,往上加,直达 s ≤ 补全的数字和 s \leq 补全的数字和 s≤补全的数字和,最后判断两者是否相等,如果相等就说明可以补全,YES。否则NO
#include <iostream>
#include <algorithm>
#define int long long
using namespace std;
const int N = 2*1e5+10;
string s;
int n;
char ch;
bool b[N];
void sove(){
int m,s;
cin>>m>>s;
int ansmax=0;
int all=0;
while(m--){
int num;cin>>num;
ansmax=max(ansmax,num);
b[num]=true;//记录有没有
all+=num;
}
bool flag = (ansmax*(ansmax+1)/2)-all > s;
if(flag) { cout << "NO\n";return ; }
int sum=(ansmax*(ansmax+1)/2)-all;
for(int i=ansmax+1;sum<s;i++)sum+=i;//继续补全
if(sum==s)cout<<"YES\n";
else cout<<"NO\n";
}
signed main(void){
int _=1;
cin>>_;
while(_--)sove();
return 0;
}
C. Thermostat
Example
input
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
output
0
2
3
-1
1
-1
3
1
3
-1
题意:
你可以从数字 a a a变到数字 b b b,但得要满足: ∣ a − b ∣ > = x |a-b|>=x ∣a−b∣>=x and l ≤ b ≤ r l \leq b \leq r l≤b≤r
现在给出 l , r , x , a , b l,r,x,a,b l,r,x,a,b,问能不能从数字 a a a变到数字 b b b,如果能输出最小操作数,否则输出-1
题解:
分情况讨论:
1.如果 a = = b a==b a==b,不需要操作,输出 0
2.如果 ∣ a − b ∣ > = x |a-b|>=x ∣a−b∣>=x and l ≤ b ≤ r l \leq b \leq r l≤b≤r ,当然题目给出的 b b b一定满足 l ≤ b ≤ r l \leq b \leq r l≤b≤r,所以只需要判断前面,这样执行一次即可!输出 1
3.如果满足 ∣ r − a ∣ > = x |r-a|>=x ∣r−a∣>=x && ∣ r − b ∣ > = x |r-b|>=x ∣r−b∣>=x or ∣ a − l ∣ > = x |a-l|>=x ∣a−l∣>=x && ∣ b − l ∣ > = x |b-l|>=x ∣b−l∣>=x,那么我们可以想成 a a a和 b b b分别经过一次操作可以变成同一个数,那么合起来就算操作两次,输出2
4.如果a,b很近,但两个数可以分别跳到对方端点,那么就可以执行三次操作结束。
如果以上都不行那就无法,-1
#include <iostream>
#include <algorithm>
#define int long long
#define end(x) {cout<<x<<endl;return;}
using namespace std;
const int N = 2*1e5+10;
void sove(){
int l,r,x;
cin>>l>>r>>x;
int a,b;
cin>>a>>b;
if(a==b)end(0);
if(abs(a-b)>=x)end(1);
if(r-max(a,b)>=x||min(a,b)-l>=x)end(2);
if(r-a>=x&&b-l>=x||r-b>=x&&a-l>=x)end(3);
end(-1);
}
signed main(void){
int _=1;
cin>>_;
while(_--)sove();
return 0;
}