arc123 C、D 题解(haven't finish.

link
感悟:其实,一道题不妨从样例入手。

C

考场上 dfs “水过去” 的(感觉可以剪掉很多枝,常数 1500),考后发现是正解(?
至于证明,现在不想理解,以后来填吧。

#include <cstdio>
#include <algorithm>
#include <cmath>
#include <cstring>
#define LL long long
using namespace std;
int T, ans, maxx, i, g;
LL n, t, f, no;
bool dfs(LL t, int nyhsb, int limit_, int las) {
//	printf("|%lld %d %d %d|\n", t, nyhsb, limit_, las);
	if(t == 0) return (!nyhsb);
	int g = t % 10, flag = 0; g -= nyhsb;
	if(g == -1) g = 9, flag = 1;
	if((int)ceil(g / 3.0) <= las) {
		
		if(las == 0x3f3f3f3f && dfs(t / 10, flag, 1, min(las, g))) return 1;
		if(las != 0x3f3f3f3f && dfs(t / 10, flag, 1, min(las, g))) return 1;
	}
//	if(g + 10 <= i * 3) {
//	printf("rnm:%d %d %d\n", t, (int)ceil((g + 10) / 3.0), g);
	if((int)ceil((g + 10) / 3.0) > las) return 0;
	
	if(las == 0x3f3f3f3f && dfs(t / 10, 1, 1, min(las, g + 10))) return 1;
	if(las != 0x3f3f3f3f && dfs(t / 10, 1, 1, min(las, g + 10))) return 1;
//	}
	return 0;
}
int main() {
	scanf("%d", &T); ans = 0;
	while(T --) {
		scanf("%lld", &n); ans = 0;
		for(i = 1; ; i ++) {
			t = n;
//			if(i <= 3) {
//				no = 0; t = n; maxx = 0; f = 0;
//				while(t) {
//			//		printf("|%d %lld %d|\n", i, t, f);
//					g = t % 10; t /= 10;
//					if(g > i * 3) { no = 1; break; }
//					else if((int)ceil(g / 3.0) == i) f = 1;
//					else if(!f) { no = 1; break; }
//				}
//				if(no) continue; ans = i; break;
//			}
			if(dfs(t, 0, 0, i)) { ans = i; break; }
		//	if(i > 100) { printf("NYH yydsb!"); break; }
		}
		printf("%d\n", ans);
	}
	return 0;
} 
/*
2
40
9025745
*/

D

因为考场上将 Ci 替换成了 AiBi,现在就按照这个讲吧,其实不换直接做也可以。。
由题意得 BiBi+1AiBiAi+1Bi+1Bi+1Bi+max(0,Ai+1Ai)ans=|Bi|+|AiBi|。不妨找找 B 序列的关系,考虑两种情况。

1.Ai+1Ai,贪心地来想,我们肯定要使 Bi+1Ai+1Bi+1 都为正数。即 Bi+1 为正数,并且在可能的范围内最小,则 Bi+1=Bi+Ai+1Ai
2.Ai+1<AiBi+1=Bi

然后就结了。ans=|d+B1|+|cB1|cd 为常数,可用上面的柿子计算)。把 |B1| 看成 |0B1|,然后这道题就是求一个中位数。暴力跑是 O(nlog2(n))
这里有一个 trick,用类似快排的东西找第 k 大数是 O(n) 的。

暴力跑:

```cpp
#include <cstdio>
#include <algorithm>
#include <cmath>
#include <cstring>
#define LL long long
using namespace std;
const int MAXN = 4e5 + 5;
int n, a[MAXN];
LL ans, c[MAXN];
int main() {
	scanf("%d", &n);
	for(int i = 1; i <= n; i ++) scanf("%d", &a[i]);
	for(int i = 1; i <= n; i ++) {
		if(a[i] >= a[i - 1]) c[i] = c[i - 1] + a[i] - a[i - 1];
		else c[i] = c[i - 1];
	}
	for(int i = n + 1; i <= 2 * n; i ++) c[i] = a[i - n] - c[i - n];
	for(int i = 1; i <= n; i ++) c[i] = -c[i];
	sort(c + 1, c + 1 + 2 * n);
	for(int i = 1; i <= 2 * n; i ++) ans += abs(c[i] - c[n]); printf("%lld", ans);
	return 0;
}

</details>
posted @   Saintex  阅读(155)  评论(0编辑  收藏  举报
编辑推荐:
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
阅读排行:
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】
点击右上角即可分享
微信分享提示