题解
难度分布
F
题目大意
给你一个字符串,前三个字符需要是‘A’, ‘B’, ‘C’,后面的数字需要在1 ~ 349之间,并且不能等于316。
题目思路
跟着题目走即可,同时要注意不能为0和316。
题目代码
#include<stdio.h>
#include<string.h>
#define N 15
char s[N];
int main(){
scanf("%s", s);
int date = 0;
for(int i = 3;i < strlen(s);i ++){
date = date * 10 + int(s[i] - '0');
}
if(s[0] == 'A' && s[1] == 'B' && s[2] == 'C' && date != 316 && date <= 349 && date > 0){
printf("Yes\n");
}else{
printf("No\n");
}
return 0;
}
星✌的题解:
#include<bits/stdc++.h>
using namespace std;
using ll = long long;
const int N = 1e7 + 10;
const int M = 5e4 + 10;
#define IOS ios::sync_with_stdio(false),cin.tie(0), cout.tie(0)
int main() {
char a, b, c;
int n, x;
scanf("%c%c%c%d", &a, &b, &c, &n);
if (n < 350 && n != 316 && n > 0) printf("Yes");
else printf("No");
return 0;
}
E
题目大意
给你一个数,然后让你输出一个相应长度的字符串,当第i个字符,i为三的倍数,这个字符为’x’,否则为‘o’。
题目思路
跟着题目走
题目大意
#include<stdio.h>
#include<string.h>
int main(){
int n;
scanf("%d", &n);
for(int i = 1;i <= n;i ++){
printf("%c", (i % 3 == 0 ? 'x' : 'o'));
}
return 0;
}
B
题目大意
题目思路
一看样例就知道要求的是前面n - 1个数的和的相反数。
题目代码
#include<stdio.h>
#include<string.h>
int main(){
int n;
scanf("%d", &n);
int ans = 0;
for(int i = 0;i < n - 1;i ++){
int x;
scanf("%d", &x);
ans += x;
}
ans = -ans;
printf("%d\n", ans);
return 0;
}
G
题目大意
题目思路
也是跟着题目走就行。
题目代码
#include<stdio.h>
#include<string.h>
#define N 110
char a[N][N], b[N][N];
int main(){
int n;
scanf("%d", &n);
for(int i = 0;i < n;i ++) scanf("%s", a[i]);
for(int i = 0;i < n;i ++) scanf("%s", b[i]);
for(int i = 0;i < n;i ++){
for(int j = 0;j < n;j ++){
if(a[i][j] != b[i][j]){
printf("%d %d\n", i + 1, j + 1);
return 0;
}
}
}
return 0;
}
C
题目大意
给你一个字符串,看这个字符串好不好,好的要求是1~最大的字母出现次数中满足该次数的字母的个数要不是0,要不是2,否则这个字符串不好。
题目思路
先遍历一遍字符串,看一下每个字母的出现次数,再遍历一下26个字母来看看,每个出现次数对应的字母的个数,然后不满足条件的No,满足的Yes。
题目代码
#include<stdio.h>
#include<string.h>
#define N 110
char s[N];
int cnt[N] = {0}, ans[N] = {0};
int main(){
scanf("%s", s);
int m = 0;
for(int i = 0;i < strlen(s);i ++){//看一下每个字母的出现次数
cnt[s[i] - 'a'] ++;
m = (m > cnt[s[i] - 'a'] ? m : cnt[s[i]- 'a']);//寻找最大的出现次数
}
for(char i = 'a';i <= 'z';i ++){//再遍历一下26个字母来看看,每个出现次数对应的字母的个数
ans[cnt[i - 'a']] ++;
}
for(int i = 1;i <= m;i ++){
if(ans[i] != 0 && ans[i] != 2){
printf("No\n");
return 0;
}
}
printf("Yes\n");
return 0;
}
D
题目大意
题目思路
就是匹配子序列,但是要注意一定要按顺序匹配,就比如t为abc
,这个时候s必须要先匹配要a
,然后才能匹配b
,然后如果t的结尾如果是x
的话,只需要匹配前面两个,反之要匹配三个。
题目代码
#include<stdio.h>
#include<string.h>
#define N 100010
char s[N], t[4];
int main(){
scanf("%s%s", s, t);
if(t[2] == 'X'){
int k = 0;//k为t匹配的下标
for(int i = 0;i < strlen(s);i ++){
if(char(s[i] - 'a' + 'A') == t[k]){
k ++;//匹配到前面的,开始加一匹配下一个
}
}
if(k >= 2){//前两个匹配成功此时k为2,所以k至少是2
printf("Yes\n");
}else{
printf("No\n");
}
}else{
int k = 0;
for(int i = 0;i < strlen(s);i ++){
if(char(s[i] - 'a' + 'A') == t[k]){
k ++;
}
}
if(k >= 3){3个匹配成功此时k为3,所以k至少是3
printf("Yes\n");
}else{
printf("No\n");
}
}
return 0;
}
A
题目大意
看样例更好理解一点
题目思路
思路一(Hard):
本题思路一前置知识点:数学 + 位运算 + 结构体 + 排序
本题的思路来源是未来我们要学的一种高级算法和高级数据结构 ---- 线段树的原理,学完这个算法之后我们看这道题可能就相对比较简单哦,当然不学也是完全可以做出来的。
我们做题要学会画图,接下来是以第一个样例表示的一张图:
这是一种自下而上的解决方案, 我们可以从下往上检查线段。从最底层的节点开始,确定两端是否必须选择长度为 2 i的线段。
思路二(Easy):
思路二的话大家也是要看上面内张图来理解,每次我尽可能的来选取大的线段的即可。
题目代码
思路一:
#include<stdio.h>
#include<string.h>
typedef long long ll;
#define N 100
struct node{
ll l, r;
}ans[N];
bool cmp(node x, node y){
if(x.l != y.l) return x.l < y.l;
return x.r < y.r;
}
int main(){
ll L, R;
scanf("%lld %lld", &L, &R);
ll i = 0;
int k = 0;
while(L < R){//可以边看代码边看上面的图来理解
if((L >> i) & 1){//看L的二进制的第i位是不是1
ans[k ++] = {L, L + (ll(1) << i)};
L += (ll(1) << i);
}
if((R >> i) & 1){
ans[k ++] = {R - (ll(1) << i), R};
R -= (ll(1) << i);
}
i += 1;
}
for(int j = 0;j < k - 1;j ++){//冒泡排序
for(int z = 0;z < k - 1 - j;z ++){
if(!cmp(ans[z], ans[z + 1])){
ll xx = ans[z + 1].l, yy = ans[z + 1].r;
ans[z + 1].l = ans[z].l, ans[z + 1].r = ans[z].r;
ans[z].l = xx, ans[z].r = yy;
}
}
}
printf("%d\n", k);
for(int i = 0;i < k;i ++){
printf("%lld %lld\n", ans[i].l, ans[i].r);
}
return 0;
}
思路二:
下面的代码本来是要用结构体的,但是赛场上根据蔡泽垲同学的代码进行了修改,在此对蔡泽垲同学提出表扬,当然赛场上能做出这道题的孟晖同学也很棒。
#include<stdio.h>
#include<string.h>
#include<math.h>
typedef long long ll;
#define N 100000
ll ans[N];
int main(){
ll L, R;
scanf("%lld %lld", &L, &R);
int k = 0;
while(L < R){
for(ll i = 60;i >= 0;i --){//尽可能选大的线段
ll w = ll(pow(2, i));
if((L + w <= R) && (L % w == 0)){
ans[k ++] = L;
ans[k ++] = L + w;
L += w;
break;
}
}
}
printf("%d\n", k / 2);//上一个L + w会和下一个L相等,所以要除2
for(int i = 0;i < k;i += 2){
printf("%lld %lld\n", ans[i], ans[i + 1]);
}
return 0;
}