Codeforces Round #668 Div. 2

A. Permutation Forgery

输入的数组倒序输出即可。。。

  #include <iostream>
  #include <algorithm>
  #include <cstdio>
  #include <cmath>
  #include <string>
  #define lc(i) (2*i+1)
  using namespace std;
  typedef long long ll;
  const ll mod = 1e6 + 1e6+5;
  ll INF = 1e18;
  ll ans = 0;
  int dataa[mod] = {}; 
  int tmpa[mod] = {};
  int min(int b, int a) { if (a > b)return b; return a; }
  int main()
  {
      ll n;
      cin >> n;
      while (n--)
      {
	      ll m;
	      cin >> m;
	      for (int i = 0; i < m; i++)scanf("%d", &dataa[i]);
	      for (int i = m - 1; i >= 0; i--)printf("%d ", dataa[i]);
	      printf("\n");
      }
  }

B. Array Cancellation

给定一个总和为0的有正负数的数列。可以进行以下操作:
选定两个数一个加一一个减一,如果加一的数在减一数的左边,则有一花费,反之没要。问需要多少花费能让数列全变成0。
用一个cnt存当前能够使用的正数的和,遇到负数就取出正数与其中和,遇到正数就加上,cnt最小为0。到末尾时输出cnt。

  #include <iostream>
  #include <algorithm>
  #include <cstdio>
  #include <cmath>
  #include <string>
  #define lc(i) (2*i+1)
  using namespace std;
  typedef long long ll;
  const ll mod = 1e6 + 1e6+5;
  ll INF = 1e18;
  ll ans = 0;
  int dataa[mod] = {}; 
  int tmpa[mod] = {};
  int min(int b, int a) { if (a > b)return b; return a; }
  int main()
  {
      ll n;
      cin >> n;
      while (n--)
      {
	      ll m;
	      cin >> m;
	      for (int i = 0; i < m; i++)scanf("%d", &dataa[i]);
	      ll pa = 0;
	      for (int i = 0; i < m; i++) {
		      if (dataa[i] < 0) {
			      pa += dataa[i];
			      if (pa < 0)pa = 0;
		      }
		            else pa += dataa[i];
	      }
	      cout << pa << '\n';

      }
  }

C. Balanced Bitstring

字符串中,每隔k个的字符应该是相同的,所以我们可以先跑一遍确定前k个的字符,最后确定前k个字符满不满足0和1各一半即可。

  #include <iostream>
  #include <algorithm>
  #include <cstdio>
  #include <cmath>
  #include <string>
  #define lc(i) (2*i+1)
  using namespace std;
  typedef long long ll;
  const ll mod = 1e6 + 1e6+5;
  ll INF = 1e18;
  ll ans = 0;
  int dataa[mod] = {}; 
  int tmpa[mod] = {};
  int min(int b, int a) { if (a > b)return b; return a; }
  int max(int a, int b) {	if (a > b)return a;	return b;}
  string s;
  void solve(int m, int k) {
      for (int i = 0; i < k; i++) {
	      for (int j = i; j < s.length(); j += k) {
		      if (s[j] == '?')continue;
		      if (s[i] == '?' && s[j] != '?')s[i] = s[j];
		      else if (s[i] != '?' && s[i] != s[j]) { cout << "NO\n"; return; }
	      }
      }
      int cnt = 0,ans=0;
      for (int i = 0; i < k; i++) {
	      if (s[i] == '1')ans++;
	      if (s[i] == '?')cnt++;
      }
      if (ans <= k / 2 && ans + cnt >= k / 2)cout << "YES\n";
      else cout << "NO\n";
  }
  int main()
  {
      ll n;
      cin >> n;
      while (n--)
      {
	      ll m, k;
	      cin >> m >> k >> s;
	      solve(m, k);
      }

  }

D. Tree Tag

A和B都在树的直径上移动是最优的,因此有以下几种情况
1.A B的距离小于等于da,A直接把B带走
2.db>=2da+1,B可以在A接近后走到A的反向,但是前提是有足够的空间
3.树的直径<2
da+1,B没有足够的空间放风筝,因此被带走,反之B获胜
所以我们可以先bfs出ab距离和树的直径,判断下即可
补题的时候数组开小了。。。。。疯狂wa

  #include <iostream>
  #include <algorithm>
  #include <cstdio>
  #include <cmath>
  #include <string>
  #include <cstring>
  #include<vector>
  #define lc(i) (2*i+1)
  using namespace std;
  typedef long long ll;
  ll ans = 0;
  ll k,a,b,da,db;
  vector<int> v[200000+5];
  int d[200000 + 5];
  bool vis[200000 + 5];
  int que[200000 + 5];
  void bfs(int st) {
  	      memset(d, 0, sizeof(d));
      memset(vis, 0, sizeof(vis));
      int l = 0, r = -1;
      que[++r] = st;
      vis[st] = 1;
      while (r>=l)
      {
	      int tmp = que[l++];
	      for (int i = 0; i < v[tmp].size(); i++) {
		      if (!vis[v[tmp][i]]) {
			      vis[v[tmp][i]] = 1;
			      d[v[tmp][i]] = d[tmp] + 1;
			      que[++r] = v[tmp][i];
		      }
	      }
      }
  }
  int main() {
      ll n;
      cin >> n;
      while (n--)
      {
	      cin >> k>>a>>b>>da>>db;
	      for (int i = 0; i <= k; i++)v[i] = vector<int>();
	      for (int i = 0; i < k-1; i++) {
		      int tmp1, tmp2;
		      cin >> tmp1 >> tmp2;
		      v[tmp1].push_back(tmp2);
		      v[tmp2].push_back(tmp1);
	      }
	      if (db <= da * 2 ) {
		      cout << "Alice\n";
		      continue;
	      }
	      bfs(a);
	      if (d[b] <= da) {
		      cout << "Alice\n";
		      continue;
	      }
	      bfs(1);
	      int u = 0;
	      for (int i = 0; i <= k; i++)if (d[i] > d[u])u = i;
	      bfs(u);
	      int r = 0;
	      for (int i = 0; i <= k; i++)r = max(r, d[i]);
	      if (r < 2*da+1) {
		      cout << "Alice\n";
		      continue;
	      }
	      else cout << "Bob\n";
      }


  }
posted @ 2020-09-07 14:35  PopHirasawa  阅读(165)  评论(0编辑  收藏  举报