kuangbin题单|数学训练一
数学训练(×)
脑筋急转弯
1.LightOJ1008 Fibsieve's Fantabulous Birthday 找规律
此题已经写过题解了,看@此处
2.LightOJ1010 Knights in Chessboard 找规律
没想出来,分享好题解@此处
总结就是讨论的取值,如果大于,直接取棋盘的黑色部分。
如果等于,将棋盘划分为若干个的田,剩下的部分长度只能为。的情况就是一个田加上一个空白区域,的情况就是一个田,的情况就是一个长条。
如果等于,显然每一块都可以放一个骑士,答案为。
void solve(int kase) {
cin >> m >> n;
if (n > m) swap(n, m);
if (n > 2) {
printf("Case %d: %d\n", kase, (n * m + 1) / 2);
return;
} else if (n == 2) {
int t = 0;
if (m % 4 == 3 || m % 4 == 2) t = 2;
else if (m % 4 == 1) t = 1;
else t = 0;
printf("Case %d: %d\n", kase, 4 * (m / 4) + 2 * t);
return;
} else printf("Case %d: %d\n", kase, m);
}
3.LightOJ1020 A Childhood Game 巴什博弈
本题是情况下的巴什博弈。
对于个棋子,每人每次可以拿个:
- 如果取最后子判胜,那么当时后手必胜,否则先手必胜。
简单证明:
无论先手取多少子,后手都可以取一定的量使两者和为(比如先手取个,后手则可以取个)。这使得取子变为轮和最后一轮。若最后一轮不存在,显然是后手取最后一子,故后手必胜。
- 如果取最后子判负,那么当时后手必胜,否则先手必胜。
简单证明:
取最后子判负,等价于先取完前个子的获胜,也就是判断谁先取到第个子,此时与第一种情况相同。
void solve(int kase) {
string win = "";
int m = 2;
if (s == "Bob") {
if (n % (m + 1) == 0) win = "Alice";
else win = "Bob";
} else {
if ((n - 1) % (m + 1) == 0) win = "Bob";
else win = "Alice";
}
printf("Case %d: %s\n", kase, win.c_str());
}
4.LightOJ1078 Integer Divisibility 模拟
设为,模数为,答案为。
的初始值为,显然迭代过程是。
循环直到为止。
void solve(int kase) {
LL y = k;
int ans = 1;
while (y % n != 0) {
y = (y * 10) % n + k % n;
ans++;
}
printf("Case %d: %d\n", kase, ans);
}
5.LightOJ1116 Ekka Dokka 质因数分解
显然若是奇数,一定无法分解成奇数*偶数。
继续讨论,如果可以表示成,其中是奇数,那么一定是满足最小偶数的条件的。
否则,我们对的所有质因数进行分析。要求最小偶数等价于最大奇数,最大的奇数=所有不包括的质因数之积,在实际代码中,只要不断直到为奇数即可。
void solve(int kase) {
if (n & 1LL) {
printf("Case %d: Impossible\n", kase);
return;
}
if (((n >> 1LL) & 1LL)) {
printf("Case %d: %lld %lld\n", kase, n / 2, 2);
return;
} else {
LL t = n;
while (t) {
if (t & 1LL) break;
t >>= 1LL;
}
printf("Case %d: %lld %lld\n", kase, t, n / t);
}
}
6.LightOJ1148 Mad Counting 找规律
设为出现的次数。我们举一个例子:1 1 1 1 1
可以发现,满足最小人数的分组是,
也就是说:对于同一个被分为了组,如果能被整除,,否则,即前组的人数+最后一组的人数。
void solve(int kase) {
memset(cnt, 0, sizeof(cnt));
cin >> n;
int L = inf, R = -1;
int ans = 0;
while (n--) {
int x;
cin >> x;
cnt[x]++;
L = min(L, x);
R = max(R, x);
}
for (int i = L; i <= R; i++) {
if (cnt[i] % (i + 1) != 0) ans += (cnt[i] / (i + 1)) * (i + 1) + (i + 1);
else ans += cnt[i];
}
printf("Case %d: %d\n", kase, ans);
}
7.LightOJ1179 Josephus Problem 约瑟夫环
套个递推公式就出来了,看着怪大的其实压根没爆
void solve(int kase) {
cin >> n >> k;
int ans = 0;
for (int i = 1; i <= n; i++) ans = (ans + k) % i;
printf("Case %d: %d\n", kase, ans + 1);
}
8.LightOJ1275 Internet Service Providers 小学数学
呃,一元二次方程。
int count(int x) {
return -n * x * x + c * x;
}
void solve(int kase) {
cin >> n >> c;
int ans = 0;
if (!n || !c) {
printf("Case %d: 0\n", kase);
return;
}
if (!c % (2 * n)) {
ans = c / (2 * n);
} else {
int temp = c / (2 * n);
if (count(temp) < count(temp + 1)) ans = temp + 1;
else ans = temp;
}
printf("Case %d: %d\n", kase, ans);
}
9.LightOJ1294 Positive Negative Sign 小学数学
易推得,每两组的和为,一共有组,所以答案是
void solve(int kase) {
cin >> n >> m;
LL ans = n * m >> 1LL;
printf("Case %d: %lld\n", kase, ans);
}
10.LightOJ1297 Largest Box 带精度二分
体积
一阶导可得:。
易知无整数解,令进行二分,答案带入即可。
double calc(double x) {
return (double) (x * (w - 2 * x) * (l - 2 * x));
}
double calc2(double x) {
return (double) (12 * x * x - 4 * (l + w) * x + w * l);
}
double solve2() {
double l = 0, r = w / 2.0;
double ans = 0;
while (r - l > eps) {
double mid = (l + r) / 2.0;
if (calc2(mid) > 0) l = mid, ans = l;//图像可知导函数严格递减
else r = mid - eps;
}
return ans;
}
void solve(int kase) {
cin >> l >> w;
if (w > l) swap(l, w);
double x1 = solve2();
double ans = calc(x1);
printf("Case %d: %lf\n", kase, ans);
}
分类:
题解
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!