题解
难度分布
A
题目大意
给你两个数, 分别为A和B,输出一个在0和9之间而不等于A + B(A + B <= 9)的数。
题目思路
因为9为奇数,所以我们输出9 -(A + B), 它一定不等于A + B,
题目代码
#include<stdio.h>
typedef long long ll;
int main(){
int A, B;
scanf("%d%d", &A, &B);
printf("%d", 9 - (A + B));
return 0;
}
D
题目大意
题目思路
题目怎么说,就怎么做呗
题目代码
#include<stdio.h>
typedef long long ll;
int main(){
int n, k;
scanf("%d%d", &n, &k);
for(int i = 0;i < n;i ++){
int x;
scanf("%d", &x);
if(x % k == 0) printf("%d ", x / k);
}
printf("\n");
return 0;
}
B
题目大意
给你一个二维矩阵,输出每一行值等于1的列坐标
题目思路
题目怎么说,我们就怎么做
题目代码
#include<stdio.h>
typedef long long ll;
int main(){
int n;
scanf("%d", &n);
for(int i = 1;i <= n;i ++){
for(int j = 1;j <= n;j ++){
int x;
scanf("%d", &x);
if(x == 1) printf("%d ", j);
}
printf("\n");
}
return 0;
}
F
题目大意
给你一个数n, 求不大于n的最大的即是回文数也是三的幂的数。
题目思路
n最大为1e18,同时因为要是3的幂,所以最大只需要i从1枚举到1e6,每个数的数位最大为63,所以枚举一遍同时判断回文是不可能超时的。
题目代码
#include<stdio.h>
typedef long long ll;
int a[100];
bool check(ll x){//判断是否回文
int k = 0;
while(x){
a[++ k] = (x % 10);
x /= 10;
}
bool ok = true;
for(int i = 1;i <= k;i ++){
if(a[i] != a[k - i + 1]){
ok = false;
break;
}
}
return ok;
}
int main(){
ll n;
scanf("%lld", &n);
ll ans = 0;
for(ll i = 1;i * i * i <= n;i ++){
if(check(i * i * i)){
ans = i * i * i;
}
}
printf("%lld", ans);
return 0;
}
C
题目大意
题目思路
如果我们正向扫s的话,每次执行一次,时间复杂度高达o(n^2),会tle,所以我们反向来即可。
题目代码
#include<stdio.h>
typedef long long ll;
#define N 1000100
int a[N], ans[N];
char s[N];
void solve(){
int n, m;
scanf("%d%d", &n, &m);
for(int i = 0;i < n;i ++){
scanf("%d", &a[i]);
}
scanf("%s", &s);
int l = 0, r = 0;
for(int i = 0;i < n;i ++){
if(s[i] == 'L'){
r ++;
l ++;
}
}
int mul = 1;
for(int i = n - 1;i >= 0;i --){
if(s[i] == 'L'){
mul = (mul * a[-- l]) % m;
}else{
mul = (mul * a[r ++]) % m;
}
ans[i] = mul;
}
for(int i = 0;i < n;i ++){
printf("%d ", ans[i]);
}
printf("\n");
}
int main(){
int t;
scanf("%d", &t);
while(t --){
solve();
}
return 0;
}
G
题目大意
给你n个一对l,r(l <= r)的数,看你是否可以给出一组序列A,使得Li <= Ai <= Ri, 同时序列A所有的数加起来等于0。
题目思路
首先看是否存在一个序列所有的数加起来等于0,直接根据零点定理,最大值大于0, 最小值小于0,函数单调,则中间必然存在零点。
然后我们构造序列,我们可以先存入最小值,同时观察剩下的最大值可不可以补充这些最小值,然后快不行时就赶紧补充最大值。
题目代码
#include<stdio.h>
typedef long long ll;
#define N 200010
ll ans[N], l[N], r[N];
int main(){
int n;
scanf("%d", &n);
ll lo = 0, hi = 0;
for(int i = 0;i < n;i ++){
scanf("%lld%lld", &l[i], &r[i]);
lo += l[i];//最小值
hi += r[i];//最大值
}
int cur = 0;
if(lo <= 0 && hi >= 0){//零点定理
printf("Yes\n");
int flag = 1;
for(int i = 0;i < n;i ++){
if(flag){
if(hi - (r[i] - l[i]) <= 0){
//当我们发现剩余最大值补不了l和r的差距时
flag = 0;
ans[cur ++] = (r[i] - hi);
hi = 0;
}else{
ans[cur ++] = l[i];//先拿最小的
hi -= (r[i] - l[i]);
}
}else{
ans[cur ++] = r[i];//然后全拿最大的
}
}
for(int i = 0;i < cur;i ++){
printf("%d ", ans[i]);
}
printf("\n");
}else{
printf("No\n");
}
return 0;
}
E
题目大意
题目思路
逆天神题,只能说不想评价,看代码吧
NOTE:注意scanf %c 会读入换行注意解决
题目代码
#include<stdio.h>
typedef long long ll;
#define N 5
char a[N][N];
int cnt[N];
int main(){
for(int i = 1;i <= 3;i ++){
scanf("%s", a[i]);
for(int j = 3;j >= 1;j --){
a[i][j] = a[i][j - 1];
}
for(int j = 1;j <= 3;j ++){
if(a[i][j] == '0') cnt[0] ++;
if(a[i][j] == 'X') cnt[1] ++;
}
}
int ok_X1 = ((a[1][1] == 'X' && a[1][2] == 'X' && a[1][3] == 'X') + (a[2][1] == 'X' && a[2][2] == 'X' && a[2][3] == 'X') + (a[3][1] == 'X' && a[3][2] == 'X' && a[3][3] == 'X'));
int ok_O1 = ((a[1][1] == '0' && a[1][2] == '0' && a[1][3] == '0') + (a[2][1] == '0' && a[2][2] == '0' && a[2][3] == '0') + (a[3][1] == '0' && a[3][2] == '0' && a[3][3] == '0'));
int ok_X2 = (a[1][1] == 'X' && a[2][2] == 'X' && a[3][3] == 'X') + (a[1][3] == 'X' && a[2][2] == 'X' && a[3][1] == 'X');
int ok_O2 = (a[1][1] == '0' && a[2][2] == '0' && a[3][3] == '0') + (a[1][3] == '0' && a[2][2] == '0' && a[3][1] == '0');
int ok_X3 = ((a[1][1] == 'X' && a[2][1] == 'X' && a[3][1] == 'X') + (a[1][2] == 'X' && a[2][2] == 'X' && a[3][2] == 'X') + (a[1][3] == 'X' && a[2][3] == 'X' && a[3][3] == 'X'));
int ok_O3 = ((a[1][1] == '0' && a[2][1] == '0' && a[3][1] == '0') + (a[1][2] == '0' && a[2][2] == '0' && a[3][2] == '0') + (a[1][3] == '0' && a[2][3] == '0' && a[3][3] == '0'));
int ok_O = ok_O1 + ok_O2 + ok_O3;
int ok_X = ok_X1 + ok_X2 + ok_X3;
if(ok_O && ok_X){//不可能同时赢
printf("illegal\n");
return 0;
}
if(cnt[0] > cnt[1]){//0不可能大于x
printf("illegal\n");
return 0;
}
if(cnt[1] > cnt[0] + 1){//x走一步0就要走一部
printf("illegal\n");
return 0;
}
if(ok_O && !ok_X){
if(ok_O1 > 1 || ok_O3 > 1 || cnt[1] != cnt[0]){//不光有一行赢,同时赢了就不要再下了
printf("illegal\n");
}else{
printf("the second player won\n");
}
return 0;
}
if(!ok_O && ok_X){
if(ok_X1 > 1 || ok_X3 > 1 || cnt[1] != cnt[0] + 1){
printf("illegal\n");
}else{
printf("the first player won\n");
}
return 0;
}
if(cnt[0] + cnt[1] == 9){//平局
printf("draw\n");
return 0;
}
if(cnt[0] < cnt[1]){
printf("second\n");
}else{
printf("first\n");
}
return 0;
}