前言
虽然这次比赛不限制编程语言,但为了保证大家都能看懂题解中的代码,本次题解使用C语言进行编码。
A 赛博银河编程大作战
CV输出即可,字符串里有双引号可以使用转义字符。
#include <stdio.h>
int main()
{
printf("I AK the sixth \"Chasing Dreams in Space, Compiling the Future\" Fun Code Programming Competition of the School of Computer Science and Engineering.");
return 0;
}
B 基建工程
简单的输入输出题,没什么好说的。
#include <stdio.h>
#include <math.h>
int main()
{
int a;
char b;
double c;
scanf("%d %c %lf", &a, &b, &c);
printf("%d %c %.2lf", abs(a), b - 32, c);
return 0;
}
C 神秘的礼物盒I
观察题目可知能对答案做出贡献的运算只有加法和乘法,因此一共只有四种情况,枚举这四种情况然后取最大值即可。
#include <stdio.h>
int main()
{
int a, b, c; scanf("%d %d %d", &a, &b, &c);
int ans = 0;
if(a + b + c > ans) ans = a + b + c;
if(a * b + c > ans) ans = a * b + c;
if((a + b) * c > ans) ans = (a + b) * c;
if(a * b * c > ans) ans = a * b * c;
printf("%d", ans);
return 0;
}
D 社交的手腕
令我的带出价值为 ,小航的带出价值为
。
当 时,此时不用操作就能使我的带出价值 ≥ 小航的带出价值。
反之我们可以选择段 ,使用后使我的带出价值将 ≥ 小航的带出价值。
因此无论情况如何,只需要输出 Yes
就行了。
不知道大家是不是被题面吓到了,过这个题的人意外的少。
#include <stdio.h>
int main()
{
int t; scanf("%d", &t);
while(t --) printf("Yes\n");
return 0;
}
E 神秘的礼物盒Ⅱ
可以发现数据范围变了,增加了负数,因此要判断的情况也变多了。
不过就算这样,总的情况依然不多,直接暴搜就可以了。
还有要记得开 long long ,除法要判断分母不为 0 。
#include <stdio.h>
#define ll long long
ll a[4], ans = -4e18;
ll max(ll a, ll b) {return a > b ? a : b;}
void dfs(ll x, int dep) {
if(dep == 4) {
ans = max(ans, x);
return;
}
dfs(x + a[dep], dep + 1);
dfs(x - a[dep], dep + 1);
dfs(x * a[dep], dep + 1);
if(a[dep] != 0) dfs(x / a[dep], dep + 1);
}
int main()
{
for(int i = 1; i <= 3; ++ i) scanf("%lld", &a[i]);
dfs(a[1], 2);
printf("%lld", ans);
return 0;
}
对于没学过算法设计的同学来说,这显然有些超纲了。那我们不妨换种思路,既然数组中的元素可以通过下标枚举,那操作是否也可以通过数组下标枚举呢?答案是可以的!把操作封装成函数,再使用函数指针就好了。
#include <stdio.h>
#define ll long long
ll add(ll x, ll y) {return x + y;}
ll sub(ll x, ll y) {return x - y;}
ll mul(ll x, ll y) {return x * y;}
ll div(ll x, ll y) {return x / y;}
ll max(ll x, ll y) {return x > y ? x : y;}
ll (* func[])(ll, ll) = {add, sub, mul, div};
int main()
{
ll a, b, c; scanf("%lld %lld %lld", &a, &b, &c);
ll ans = -4e18;
for(int i = 0; i < 4; ++ i) {
if(b == 0 && i == 3) continue;
ll x = func[i](a, b);
for(int j = 0; j < 4; ++ j) {
if(c == 0 && j == 3) continue;
ans = max(ans, func[j](x, c));
}
}
printf("%lld", ans);
return 0;
}
对于只会C语言的同学来说,函数指针确实还是比较难想到,因此这里再提供一种只用到C语言基本语法的解法。
#include <stdio.h>
#define ll long long
ll a[3], b[4];
ll max(ll x, ll y) {return x > y ? x : y;}
int main()
{
scanf("%lld %lld %lld", &a[0], &a[1], &a[2]);
b[0] = a[0] + a[1];
b[1] = a[0] - a[1];
b[2] = a[0] * a[1];
b[3] = (a[1] != 0 ? a[0] / a[1]: -2e9);
ll ans = -4e18;
for(int i = 0; i < 4; ++ i) {
if(a[1] == 0 && i == 3) continue;
ans = max(ans, b[i] + a[2]);
ans = max(ans, b[i] - a[2]);
ans = max(ans, b[i] * a[2]);
if(a[2] != 0) ans = max(ans, b[i] / a[2]);
}
printf("%lld", ans);
return 0;
}
可以发现代码其实也没有长多少,不过这题毕竟是简单题,不用写很长的代码也是应该的~
F 提瓦特质数大冒险
这个题主要考循环和素数判断,如果素数判断的时间复杂度大于 会被卡掉。
本来以为这个题过的人会挺多的,没想到那么多人不会翻转数位。
#include <stdio.h>
int main()
{
int n; scanf("%d", &n);
while(n --) {
int x; scanf("%d", &x);
int y = 0;
while(x) {
y += x % 10, x /= 10;
if(x) y *= 10;
}
int flag = (y > 1);
for(int i = 2; i <= y / i; i ++) {
if(y % i == 0) {
flag = 0;
break;
}
}
if(flag) printf("Yes\n");
else printf("No\n");
}
return 0;
}
G 音盒谜题
音盒里的东西非常多,但是只需要交换音盒。因此我们用一个指针数组记录每个音盒的地址,交换时只需交换指针即可。
#include <stdio.h>
#define rep(i, s, e) for(int i = s; i <= e; ++ i)
#define N 100007
int a[11][N];
int *b[10];
int main()
{
int n, m; scanf("%d %d", &n, &m);
rep(i, 1, n) rep(j, 1, m) scanf("%d", &a[i][j]);
rep(i, 1, n) b[i] = a[i];
int k; scanf("%d", &k);
while(k --) {
int x, y; scanf("%d %d", &x, &y);
int *tmp = b[x];
b[x] = b[y];
b[y] = tmp;
}
int q; scanf("%d", &q);
while(q --) {
int x; scanf("%d", &x);
rep(i, 1, m) printf("%d ", b[x][i]);
printf("\n");
}
return 0;
}
H 星际货币兑换
首先要判断是否需要再增加货币,需要将所有类型的货币统一换算成最低一级的货币。
之后如果要再增加货币的话,对于每一级货币,需要增加的数量为 。
#include <stdio.h>
#define ll long long
#define N 15
ll x[N], a[N], b[N], ans[N];
int n;
ll getsum(ll a[]) {
ll res = a[1];
for(int i = 2; i <= n; ++ i) res = res * x[i] + a[i];
return res;
}
int main()
{
scanf("%d", &n);
for(int i = 2; i <= n; ++ i) scanf("%lld", &x[i]);
for(int i = 1; i <= n; ++ i) scanf("%lld", &a[i]);
for(int i = 1; i <= n; ++ i) scanf("%lld", &b[i]);
ll have = getsum(a), need = getsum(b);
if(have >= need) {
for(int i = 1; i <= n; ++ i) printf("0 ");
} else {
ans[n] = need - have;
ll k = 1;
for(int i = n - 1; i >= 1; -- i) {
k *= x[i+1], ans[i] = (need - have + k - 1) / k;
}
for(int i = 1; i <= n; ++ i) printf("%lld ", ans[i]);
}
return 0;
}
I 指针与心跳的二重奏
模拟题,代码最长的一集,把链表的基本操作考了个遍。细节很多,不建议在这个题上花费太多时间。
#include <stdio.h>
#include <string.h>
#define N 1005
typedef struct Node {
char addr[10];
int val;
int next;
} Node;
Node list[N];
int tot;
int find(char ad[]) {
int res = 0;
while(strcmp(list[res].addr, ad) && list[res].next) res = list[res].next;
return res;
}
void insert(int idx) {
char ad[10];
int x; scanf("%s %d", ad, &x);
list[++ tot].next = list[idx].next;
list[idx].next = tot;
for(int i = 0; i < 8; ++ i) list[tot].addr[i] = ad[i];
list[tot].val = x;
}
void del(char ad[]) {
int idx = 0;
while(list[idx].next && strcmp(list[list[idx].next].addr, ad)) idx = list[idx].next;
if(list[idx].next) list[idx].next = list[list[idx].next].next;
}
void swap(int x, int y) {
int tmp = list[x].val;
list[x].val = list[y].val;
list[y].val = tmp;
for(int i = 0; i < 8; ++ i) {
char c = list[x].addr[i];
list[x].addr[i] = list[y].addr[i];
list[y].addr[i] = c;
}
}
int main()
{
int n; scanf("%d", &n);
memset(list, 0, sizeof(Node) * (n + 1));
for(int t = 1; t <= n; ++ t) {
int op; scanf("%d", &op);
if(op == 1) {
char tad[10]; scanf("%s", tad);
insert(find(tad));
} else if(op == 2) {
char tad[10]; scanf("%s", tad);
del(tad);
} else {
char s[10], t[10]; scanf("%s %s", s, t);
swap(find(s), find(t));
}
}
for(int i = list[0].next; i; i = list[i].next) {
printf("%s %d\n", list[i].addr, list[i].val);
}
return 0;
}
J 神秘的礼物盒Ⅲ
命题人的得意之作,如果你会递归这题就会很简单,不会的话就非常难。然后你会发现其实那个 没有什么用。
#include <stdio.h>
#define ll long long
ll n, ans;
ll solve() {
int op;
if(scanf("%d", &op) == EOF) return ans;
if(op == 1) {
char c; scanf("%s", &c);
printf("(");
ll x = solve();
printf(" %c ", c);
ll y = solve();
printf(")");
if(c == '+') ans = x + y;
if(c == '-') ans = x - y;
if(c == '*') ans = x * y;
if(c == '/') ans = x / y;
return ans;
} else {
ll x; scanf("%lld", &x);
printf("%lld", x);
return x;
}
return 0;
}
int main()
{
int n; scanf("%d", &n);
printf("\n%lld", solve());
return 0;
}