hnit第六次积分赛

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();
}

依次考虑 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;
  }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值