Educational Codeforces Round 123 A~D

A. Doors and Keys

题意:
R、G、B三种颜色大门 必须用r、g、b颜色的钥匙开,钥匙必须在前面读到才能开门。
欣赏一下发烧降智代码:

inline void solve()
{
    
    
  string s;
  cin >> s;
  map<char, bool> m;
  bool flag = true;
  for (int i = 0; i < 6; i++)
  {
    
    
    if (s[i] == 'r')
    {
    
    
      m['R'] = true;
      continue;
    }
    if (s[i] == 'g')
    {
    
    
      m['G'] = true;
      continue;
    }
    if (s[i] == 'b')
    {
    
    
      m['B'] = true;
      continue;
    }
    if (m[s[i]])
      continue;
    else
    {
    
    
      flag = false;
      break;
    }
  }
  if (flag)
    cout << "YES" << endl;
  else
    cout << "NO" << endl;
}

再欣赏一下榜一大哥的睿智代码:

		string s;
		cin >> s;
		set < char > st;
		bool ch = true;
		for (char c : s) {
    
    
			if ('a' <= c && c <= 'z')
				st.insert(c);
			else
				ch = ch && st.count(c - ('A' - 'a'));
		}
 
		if (ch)
			cout << "YES\n";
		else
			cout << "NO\n";

其中的st.count(c - ('A' - 'a')刚好把大写字母转化为小写字母 再配合bool值使用 堪称绝妙。想不到A题也能学到东西。

B. Anti-Fibonacci Permutation

题意:反斐波那契序列,满足 P i ≠ P i − 1 + P i − 2 P_i \not= P_{i-1}+P_{i-2} Pi=Pi1+Pi2 。给数字n就输出n组(刚开始没看到这个条件wa了一发)

思路:先构造用全排列函数判断一下 如果是就输出,结果用的是升序全排列导致T掉了,然后换成降序。
降智代码:

int n;
  cin >> n;
  for (int i = 0; i < n; i++)
    a[i] = n - i;
  cnt = 0;
  do
  {
    
    
    bool flag = false;
    for (int i = 2; i < n; i++)
    {
    
    
      if (a[i] == a[i - 1] + a[i - 2])
      {
    
    
        flag = true;
        break;
      }
    }
    if (flag == false && cnt != n)
    {
    
    
      for (int i = 0; i < n; i++)
      {
    
    
        cout << a[i] << " ";
      }
      cout << endl;
      cnt++;
    }
    if (cnt == n)
      break;
  } while (prev_permutation(a, a + n));

大佬代码:

		scanf("%d", &n);
        if (n == 3) {
    
    
            printf("3 2 1\n");
            printf("1 3 2\n");
            printf("3 1 2\n");
        } else
            for (int i = 0; i < n; i++) {
    
    
                vector <int> seq;
                for (int j = i; j > 0; j--)
                    seq.push_back(j);
                for (int j = n; j > i; j--)
                    seq.push_back(j);
                for (int j = 0; j < seq.size(); j++)
                    printf("%d%c", seq[j], j + 1 < seq.size()? ' ': '\n');
            }

C. Increase Subarray Sums

题意:
在这里插入图片描述
思路:迭代到k,然后迭代到有最大总和的那段。由于x为非负数,增加段内的元素总是最理想的。因此,如果k≤l,那么该段的总和就会增加k⋅x。否则,只有段内的元素会影响总和,因此,它将增加l⋅x。这可以写成min(k,l)-x。

注意,我们只关心每个段的两个参数。它的长度和它的总和。此外,如果有几个段具有相同的长度,我们只关心总和最大的那一个。

inline void solve()
{
    
    
  int n, x;
  cin >> n >> x;

  vector<int> a(n);
  for (int i = 0; i < n; i++)
  {
    
    
    cin >> a[i];
  }

  vector<int> f(n + 1, -1E9);
  f[0] = 0;
  for (int i = 0; i < n; i++)
  {
    
    
    int s = 0;
    for (int j = i; j < n; j++)
    {
    
    
      s += a[j];
      f[j - i + 1] = max(f[j - i + 1], s);
    }
  }

  for (int k = 0; k <= n; k++)
  {
    
    
    int ans = 0;
    for (int i = 0; i <= n; i++)
    {
    
    
      ans = max(ans, f[i] + min(k, i) * x);
    }
    cout << ans << " \n"[k == n];
  }
}

D

周末补

猜你喜欢

转载自blog.csdn.net/qq_45148277/article/details/126313955