A 数学
我们设 m=k(k+1)/2(k∈N+),也就是 [1,k]内所有整数的和。可以证明对于任意一个正整数 n,都有n=m−x,其中 x 是[1,k] 中的一个整数。
#pragma GCC optimize ("O2")
#include <bits/stdc++.h>
using namespace std;
void solve(){
int n;
cin>>n;
//(1+k)*k/2
int k=0;
for(int i=1;;i++){
if((i*(i+1)/2)>=n){
k=i;
break;
}
}
cout<<k<<endl;
}
signed main() {
int T=1;
//cin>>T;
while(T--)
solve();
}
B 贪心
首先对数组排序
让最大数减去非最小数的负数,让最小数减去非最大数的非负数,最后相减。
#include <bits/stdc++.h>
using namespace std;
#define FAST cin.tie(0), cout.tie(0), ios::sync_with_stdio(false)
#define ll long long
#define endl "\n"
void solve(){
int n;
cin >> n;
vector<int> a(n+1);
for(int i = 1; i <= n; ++i){
cin >> a[i];
}
sort(a.begin()+1, a.end());
int ans = a[n];
if(n == 2){
ans = a[2]-a[1];
cout << ans << endl;
return ;
}
for(int i = 2; i <= n-1; ++i){
if(a[i] > 0){
a[1] -= a[i];
}else{
ans -= a[i];
}
}
ans -= a[1];
cout << ans <<endl;
}
/*
5
-2 -1 0 1 2
*/
signed main() {
FAST;
int T=1;
//cin >> T;
while(T--)
solve();
}
C
依次考虑 mex = 0,1,...,n 的区间是哪一些。对于mex=i的区间,一定要包含 0, ..., i − 1 的所有元素。于是每次只需要维护 0,1,...,n中下标的最小值和最大值即可。
#include <bits/stdc++.h>
using namespace std;
#define endl "\n"
void solve(){
int n;
cin >> n;
vector<int> a(n), b(n);
for(int i = 0; i < n; ++i){
cin >> a[i];
b[a[i]] = i;
}
ll ans=0;
int l = b[0], r = b[0];
for(int i = 1; i < n; ++i){
int id=b[i];
if(id < l){
ans += 1ll * (l-id) * (n-r) * i;
l = id;
}
else if(id > r){
ans += 1ll * (l+1) * (id-r) * i;
r = id;
}
}
ans += n;
cout << ans << endl;
}
signed main() {
int T=1;
//cin >> T;
while(T--)
solve();
}
D 记忆化搜索+概率
根据题意模拟
#include <bits/stdc++.h>
using namespace std;
#define endl "\n"
void solve(){
int n, m;
cin >> n >> m;
map<pair<int, int>, double> mp;
auto dfs = [&](auto &&self, int x, int y){
if(x > 0 && y == 0)return 1.0;
if(x == 0)return 0.0;
if(mp.count({x, y})!=0)return mp[{x, y}];
double ans = 0.0;
ans+=1.0 * x / (x + y);
if(y >= 3)ans+=1.0 * y / (x + y) * (y - 1) / (x + y -1) * (y - 2) / (x + y -2) * self(self, x, y-3);
if(y >= 2)ans+=1.0 * y / (x + y) * (y - 1) / (x + y -1) * x / (x + y -2) * self(self, x-1, y-2);
mp[{x, y}]=ans;
return ans;
};
double ans=dfs(dfs, n, m);
printf("%.10lf\n", ans);
}
signed main() {
int T=1;
//cin >> T;
while(T--)
solve();
}
KK的构造
结论:任意四个连续的平方数:a,b,c,d ,满足a-b-c+d=4
证明:设x*x=a,则a-b-c+d=x*x-(x+1)*(x+1)-(x+2)*(x+2)+(x+3)*(x+3)=4
#include<bits/stdc++.h>
using namespace std;
int t;
int main()
{
cin >> t;
for (int i = 1; i <= t; i++) {
int n;
cin >> n;
int m = n % 4;
if (m == 0) cout << n << "\n";
else if (m == 1) cout << n << "\n1";
else if (m == 2) cout << n + 2 << "\n0001";
else if (m == 3) cout << n - 1 << "\n01";
for (int i = 1; i * 4 <= n; i++) cout << "1001";
if (i != t) cout << endl;
}
}