成外联赛题解

前言,第一次正规的写题解,不喜勿喷

T1 舞蹈机器⼈(dance)

题目

题意

在⼀个拥有⽆限⼤⼩的⼆维平⾯的原点处,有⼀个舞蹈机器⼈,这个机器⼈将在这个平⾯上跳舞。
这个机器⼈每次可以向⾃⼰的前⽅移动⼀个单位的⻓度,由于它需要在移动的过程中跳舞,因此,舞蹈机器⼈每移动⼀次,就必须向左或右⽅向旋转 ,即如果此次机器⼈往或下⽅向进⾏了⼀次移动,那么,下⼀次就只能往左或右⽅向进⾏⼀次移动。最开始时,它可以选择上下左右四个⽅向中的任意⼀个作为初始⽅向。现在,机器⼈根据上述规则⼀共移动了s步,请问,机器⼈最终可以到达多少个不同的终点?机器⼈到达终点时的⽅向可以忽略。

输入与输出

输入
597
输出
179400

思路

首先想到暴力(也就是DFS),通过暴力,制作一个二维的bool数组,第k步设为1,其余为0。
然后遍历这个数组,ans记录可能位置。
但很明显,这个方法它超时了。我们要采取更优化的方法,这能数学求解。
对于机器⼈的移动⽽⾔,因为第⼆次移动的⽅向必须是在第⼀次的基础上进⾏旋转,所以对于整个机器⼈的移动过程⽽⾔,每两次移动就相当于是在正⽅形的对⻆线上移动了⼀次(即斜着⾛了⼀步),也就是每两步一个周期。
因此奇(qi)数步的思路为(1+(n+1)/2)*(n+1)
偶数则为(n/2+1)*(n/2+1)
时间复杂度仅为O(1).

代码

#include<bits/stdc++.h>
using namespace std;
int main() {
//	freopen("dance.in","r",stdin);考试不加会G掉的 
//	freopen("dance.out","r",stdout);
	long long n;//十年OI一场空,不开_______见祖宗
	cin>>n;
	if(n%2==1) cout<<(1+(n+1)/2)*(n+1)<<'\n';//如思路
	else cout<<(n/2+1)*(n/2+1)<<'\n';
}

T2 划分(partition)

题目

image

思路

· 30pts
暴⼒搜索划分⽅案即可
· 60pts 使用一个动态规划维护
· 80pts 发现手玩一定是n/2
. 100pts思路
注意到⼀个关键性质gcd(a+b,c)>=gcd(a,b,c)
证明是容易的,设d=gcd(a,b,c) ,那么d|(a+b) ,于是gcd(a+b,c)>=gcd(a,b,c)肯定成⽴。
这个性质说明最优划分⼀定只会划分为两段,否则将相邻的两段合并起来⼀定更优。
于是滚⼀个前缀和,暴⼒枚举分割点即可

代码

#include <bits/stdc++.h>
#define int long long
using namespace std;
const int N=1e18;
int t,n;
vector<int> s(n + 1);
int main() {
	cin>>t;
	while (t--) {
		cin>>n;
		for (int i=1;i<=n;i++) {
			cin>>s[i];
			s[i]+=s[i-1];
		}
		int ans=0;
		for(int i=1;i<=n;i++) {
			ans=max(ans,gcd(a[i],a[n]-a[i]));
		}
		cout<<ans<<'\n'
	}
}

posted @ 2025-10-08 18:16  爱做牢笼的老龙  阅读(7)  评论(0)    收藏  举报