Q1 等差数列
由于保证了题目给出的一定是一个等差数列的部分项,且等差数列具有单调性质,所以根据大小排序后最小的
d
i
d_i
di就是所求等差数列的公差
d
d
d, 又因为求的是最小,所以
n
=
(
a
n
−
a
1
)
/
d
+
1
,
特别的,当
a
n
=
a
1
,
d
=
0
时,特判输出
a
n
s
=
n
。
n = (a_n-a_1) / d + 1,特别的,当a_n=a_1,d=0时,特判输出ans=n。
n=(an−a1)/d+1,特别的,当an=a1,d=0时,特判输出ans=n。
/*
* @Author: gorsonpy
* @Date: 2022-12-18 13:56:02
* @Last Modified by: gorsonpy
* @Last Modified time: 2022-12-18 13:56:52
*/
#include<iostream>
#include<algorithm>
using namespace std;
const int N = 1e5 + 10;
int a[N];
int main()
{
int n;
cin >> n;
for(int i = 1; i <= n; ++i) cin >> a[i];
int res = 2e9 + 1;
sort(a + 1, a + n + 1);
for(int i = 1; i < n; ++i)
{
int d = a[i + 1] - a[i];
res = min(d, res);
}
if(res == 0) cout << n << endl;
else cout << (a[n] - a[1]) / res + 1 << endl;
return 0;
}
Q2
自己没搞出来啊,没想到N = 21还可以状态压缩,一开始瞎搞了个搜索也写挂了,参考这篇博客写的: 回路计数, 记得要在本地跑出答案再交,直接交空间时间应该都爆了.
#include<iostream>
using namespace std;
using LL = long long;
const int M = 1 << 21, N = 21;
LL f[M][N];
int e[N][N];
int gcd(int a, int b)
{
return b ? gcd(b, a % b) : a;
}
void init()
{
for(int i = 1; i <= 21; ++i)
for(int j = i + 1; j <= 21; ++j)
if(gcd(i, j) == 1) e[i - 1][j - 1] = e[j - 1][i - 1] = 1;
}
int main()
{
init();
f[1][0] = 1;
for(int i = 1; i < M; ++i)
for(int j = 0; j < 21; ++j)
if(i >> j & 1)
{
for(int k = 0; k < 21; ++k)
{
if(e[k][j] && i - (1 << j) >> k & 1)
f[i][j] += f[i - (1 << j)][k];
}
}
LL ans = 0;
for(int i = 1; i <= 20; ++i) ans += f[M - 1][i];
cout << ans << endl;
return 0;
}