codeforces global round 2

A 题意:给一组数,求两个不同的数的最大距离(保证至少有两个数不同)

最大的两个数位a[i]和a[j],至少有一个在两端。贪心即可

#include <bits/stdc++.h>

using namespace std;

int main() {
  ios::sync_with_stdio(false);
  cin.tie(0);
  int n;
  cin >> n;
  vector<int> a(n);
  for (int i = 0; i < n; i++) {
    cin >> a[i];
  }
  int ans = 0;
  for (int i = 0; i < n; i++) {
    if (a[i] != a[0]) {
      ans = max(ans, i - 0);
    }
    if (a[i] != a[n - 1]) {
      ans = max(ans, n - 1 - i);
    }
  }
  cout << ans << '\n';
  return 0;
}

 

B:给定一些物品的高度。放进一个高度为h,宽度为2的箱子里(具体看题目描述吧,不知道怎么描述好),求最多放多少个

从大到小放就行。二分的话可以提高速度,但是题目的数据范围没必要

#include <bits/stdc++.h>

using namespace std;

int main() {
  ios::sync_with_stdio(false);
  cin.tie(0);
  int n, h;
  cin >> n >> h;
  vector<int> a(n);
  for (int i = 0; i < n; i++) {
    cin >> a[i];
  }
  for (int k = n; k >= 0; k--) {
    vector<int> b(a.begin(), a.begin() + k);
    sort(b.begin(), b.end());
    long long sum = 0;
    for (int i = (int) b.size() - 1; i >= 0; i -= 2) {
      sum += b[i];
    }
    if (sum <= h) {
      cout << k << '\n';
      return 0;
    }
  }
  return 0;
}

C:给定两个01矩阵,每次可以选择一个矩形来翻转它的四个顶点,求是否可以把左边的矩阵变为右边的矩阵

贪心,我也不知道怎么证明

#include <bits/stdc++.h>

using namespace std;

int main() {
  ios::sync_with_stdio(false);
  cin.tie(0);
  int h, w;
  cin >> h >> w;
  vector<vector<int>> a(h, vector<int>(w));
  vector<vector<int>> b(h, vector<int>(w));
  for (int i = 0; i < h; i++) {
    for (int j = 0; j < w; j++) {
      cin >> a[i][j];
    }
  }
  for (int i = 0; i < h; i++) {
    for (int j = 0; j < w; j++) {
      cin >> b[i][j];
    }
  }
  for (int i = 0; i < h; i++) {
    for (int j = 0; j < w; j++) {
      if (a[i][j] != b[i][j]) {
        if (i == h - 1 || j == w - 1) {
          cout << "No" << '\n';
          return 0;
        }
        a[i][j] ^= 1;
        a[i + 1][j] ^= 1;
        a[i][j + 1] ^= 1;
        a[i + 1][j + 1] ^= 1;
      }
    }
  }
  cout << "Yes" << '\n';
  return 0;
}

D:直接看题目下的图吧,比较清楚。

做法:注意到答案只和R-L有关,先对s排序,注意到第i行出现的数字且不在第i+1行出现的个数为min(s[i+1]-s[i], r-l+1),

那么我们先求出s的差分数列,然后排序,求前缀和。对于每一次询问,对s的差分序列做二分,答案根据min(s[i+1]-s[i], r-l+1)可以分为两部分,前半部分的贡献可以通过前缀和求出来,后半部分直接乘一下即可。

#include<bits/stdc++.h>
using namespace std;

using ll = long long;

const int MAXN = 1.1e5;
int N;
ll S[MAXN];
ll pref[MAXN];
const int MAXQ = 1.1e5;
int Q;

int main() {
	ios_base::sync_with_stdio(0), cin.tie(0), cout.tie(0);
	cin >> N;
	for (int i = 0; i < N; i++) cin >> S[i];
	sort(S, S + N);

	for (int i = 0; i+1 < N; i++) {
		S[i] = S[i+1] - S[i];
	}
	// the differences
	sort(S, S + N-1);
	//for (int i = 0; i < N; i++) cout << S[i] << " "; cout << endl;
	pref[0] = 0;
	for (int i = 0; i < N-1; i++) {
		pref[i+1] = pref[i] + S[i];
	}
	//for (int i = 0; i < N; i++) cout << pref[i] << " "; cout << endl;
	cin >> Q;
	for (int q = 0; q < Q; q++) {
		ll L, R; cin >> L >> R;
		ll W = R - L + 1;
		ll ind = lower_bound(S, S + N - 1, W) - S;
		cout << (N - ind) * W + pref[ind] << " \n"[q+1 == Q];
	}

	return 0;
}

E:给了一些长度为2^i的木棍,问最多可以组成多少个三角形

分析:只有两种三角形:(i, i, i)  (i ,j, j) 其中i< j

贪心(我也不知道为啥是是正确的,官方有分析 https://codeforces.com/blog/entry/66411

从小到大,先保证之前没用到的i,来组成(i, j, j),剩下的组成(j, j, j)

//贪心,每次拿剩下的还未匹配的先匹配(i, j, j) i < j,然后在匹配(j, j, j)
#include<bits/stdc++.h>
using namespace std;

using ll = long long;
const int MAXN = 3.1e5;
int N;
ll A[MAXN];

int main() {
	ios_base::sync_with_stdio(0), cin.tie(0), cout.tie(0);
	cin >> N;
	for (int i = 0; i < N; i++) cin >> A[i];

	ll tot = 0;
	ll carry = 0; // <= 3
	for (int i = 0; i < N; i++) {
		ll v = min(A[i] / 2, carry);
		tot += v;
		carry -= v;
		A[i] -= 2 * v;

		assert(A[i] <= 1 || carry == 0);

		tot += A[i] / 3;
		A[i] %= 3;

		carry += A[i];
	}
	cout << tot << '\n';

	return 0;
}

F G H题没去看。。AC的人数太少了。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值