补题:牛客寒假算法基础集训营2

比赛入口


E 做计数

做法:平方数的因子和

代码

#include<bits/stdc++.h>
#define fio ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
#define lson rt<<1, l, mid
#define rson rt<<1|1, mid+1, r
using namespace std;
typedef long long LL;
typedef pair<LL, int> pli;
typedef pair<int, int> pii;
typedef pair<LL, LL> pll;
typedef pair<double, double> pdd;
typedef map<char, int> mci;
typedef map<string, int> msi;
template<class T>
void read(T &res) {
  int f = 1; res = 0;
  char c = getchar();
  while(c < '0' || c > '9') { if(c == '-') f = -1; c = getchar(); }
  while(c >= '0' && c <= '9') { res = res * 10 + c - '0'; c = getchar(); }
  res *= f;
}
int main() {
  LL n; read(n);
  LL res = 0;
  for(LL i = 1; i * i <= n; ++i) {
    LL mid = i * i, j;
    for(j = 1; j * j < mid; ++j)
      if(mid % j == 0) {
        ++res;
        if(mid / j != j) ++res;
      }
      ++res;
  }
  cout << res << endl;
  return 0;
}

F 拿物品

做法:要使得两人差值尽可能大,是两个属性的和进行排序

代码

#include<bits/stdc++.h>
#define fio ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
#define lson rt<<1, l, mid
#define rson rt<<1|1, mid+1, r
using namespace std;
typedef long long LL;
typedef pair<LL, int> pli;
typedef pair<int, int> pii;
typedef pair<LL, LL> pll;
typedef pair<double, double> pdd;
typedef map<char, int> mci;
typedef map<string, int> msi;
template<class T>
void read(T &res) {
  int f = 1; res = 0;
  char c = getchar();
  while(c < '0' || c > '9') { if(c == '-') f = -1; c = getchar(); }
  while(c >= '0' && c <= '9') { res = res * 10 + c - '0'; c = getchar(); }
  res *= f;
}
const int N = 2e5+5;
struct xx {
  LL a, b;
  int id;
  bool operator < (const xx &c) const {
    return a + b > c.a + c.b;
  }
}obj[N];
int main() {
  int n; read(n);
  for(int i = 1; i <= n; ++i) { read(obj[i].a); obj[i].id = i; }
  for(int i = 1; i <= n; ++i) read(obj[i].b);
  sort(obj+1, obj+n+1);
  for(int i = 1; i <= n; i += 2) printf("%d ", obj[i].id);
  puts("");
  for(int i = 2; i <= n; i += 2) printf("%d ", obj[i].id);
  return 0;
}

C 算概率

做法:这题在比赛的时候想了好久啊,其实就是一个递推方程…
d p [ i ] [ j ] = d p [ i 1 ] [ j ] ( 1 p [ i ] ) + d p [ i 1 ] [ j 1 ] p [ i ] dp[i][j] = dp[i-1][j]*(1-p[i])+dp[i-1][j-1]*p[i] d p [ i ] [ j ] dp[i][j] 表示前 i i 个题目做对了 j j 道。

代码

#include<bits/stdc++.h>
#define fio ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
#define lson rt<<1, l, mid
#define rson rt<<1|1, mid+1, r
using namespace std;
typedef long long LL;
typedef pair<LL, int> pli;
typedef pair<int, int> pii;
typedef pair<LL, LL> pll;
typedef pair<double, double> pdd;
typedef map<char, int> mci;
typedef map<string, int> msi;
template<class T>
void read(T &res) {
  int f = 1; res = 0;
  char c = getchar();
  while(c < '0' || c > '9') { if(c == '-') f = -1; c = getchar(); }
  while(c >= '0' && c <= '9') { res = res * 10 + c - '0'; c = getchar(); }
  res *= f;
}
const int Mod = 1e9+7;
const int N = 2003;
LL dp[N][N], p[N];
int main() {
  int n; read(n);
  for(int i = 1; i <= n; ++i) read(p[i]);
  dp[1][1] = p[1]; dp[1][0] = (1 - p[1] + Mod) % Mod;
  for(int i = 2; i <= n; ++i) {
    for(int j = 0; j <= i; ++j) {
      dp[i][j] = (dp[i-1][j] * (1 - p[i] + Mod) % Mod + dp[i-1][j-1] * p[i] % Mod) % Mod;
    }
  }
  for(int i = 0; i <= n; ++i) cout << dp[n][i] << " ";
  cout << endl;
  return 0;
}


H 施魔法

做法:简单的01背包…排过序后就是选当前的点或者不选当前的点…

代码

#include<bits/stdc++.h>
#define fio ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
#define lson rt<<1, l, mid
#define rson rt<<1|1, mid+1, r
using namespace std;
typedef long long LL;
typedef pair<LL, int> pli;
typedef pair<int, int> pii;
typedef pair<LL, LL> pll;
typedef pair<double, double> pdd;
typedef map<char, int> mci;
typedef map<string, int> msi;
template<class T>
void read(T &res) {
  int f = 1; res = 0;
  char c = getchar();
  while(c < '0' || c > '9') { if(c == '-') f = -1; c = getchar(); }
  while(c >= '0' && c <= '9') { res = res * 10 + c - '0'; c = getchar(); }
  res *= f;
}
const int N = 3e5+5;
LL a[N], dp[N];
int main() {
  int n, k;
  read(n); read(k);
  for(int i = 1; i <= n; ++i) read(a[i]);
  sort(a+1, a+n+1);
  for(int i = 1; i <= n; ++i) dp[i] = 1e17;
  for(int i = k; i <= n; ++i)
    dp[i] = min(dp[i-k] + a[i] - a[i-k+1], dp[i-1] + a[i] - a[i-1]);
  printf("%lld\n", dp[n]);
  return 0;
}

I 建通道

做法:要找到最小的二进制位k,使得 a i a_i 这个二进制位是0, a j a_j 这个二进制位是1,答案是(去重后点数-1)*2^k

代码

#include<bits/stdc++.h>
#define fio ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
#define lson rt<<1, l, mid
#define rson rt<<1|1, mid+1, r
using namespace std;
typedef long long LL;
typedef pair<LL, int> pli;
typedef pair<int, int> pii;
typedef pair<LL, LL> pll;
typedef pair<double, double> pdd;
typedef map<char, int> mci;
typedef map<string, int> msi;
template<class T>
void read(T &res) {
  int f = 1; res = 0;
  char c = getchar();
  while(c < '0' || c > '9') { if(c == '-') f = -1; c = getchar(); }
  while(c >= '0' && c <= '9') { res = res * 10 + c - '0'; c = getchar(); }
  res *= f;
}
set<int> st;
int main() {
  int n; read(n);
  int x = 0, y = 0x7fffffff;
  int a;
  for(int i = 1; i <= n; ++i) {
    read(a);
    x |= a; y &= a;
    st.insert(a);
  }
  x = x ^ y; x = x & (-x);
  cout << (st.size()-1)*x;
  return 0;
}


J 求函数

做法:貌似是函数化简+两颗线段树维护?


发布了28 篇原创文章 · 获赞 14 · 访问量 2940

猜你喜欢

转载自blog.csdn.net/qq_43408978/article/details/104209748