【B题】Ozon Tech Challenge 2020 (Div.1 + Div.2)

在这里插入图片描述
在这里插入图片描述
题意:
题目的大致意思是尽可能进行少操作地从一个只含"("")“的字符串里,取出简单括号序列——”( )""(())“这样对称的才是简单括号序列,”()()"这样的不是 ,使得其不能再进行操作

比赛想法:
1.被尽可能少操作迷惑了,觉得肯定有两次,或者好多次才能结束的操作。一直不知道,其实要么就是操作0次,要么就是操作一次,不存在大于一次的情况。
2.其实题目有点理解错了,比赛的时候一直以为是每次尽可能多的选取简单括号序列就好了,结果其实还有个条件就是尽可能使其不能再操作没考虑到。就比如说这么一个样例——((()()))如果是第一次只能取六个这是肯定的,但是怎么取,我在想,要是取的是1,2,3,4,6,7。那么剩下的是(),所以还要再取一次。然后一直纠结怎么去了一次之后继续取。

代码:

#include <bits/stdc++.h>
using namespace std;
 
int main() {
  ios::sync_with_stdio(false);
  cin.tie(0);
  string s;
  cin>>s;
  int len=s.size();
  int sumPre=0;
  int sumNext=0;
  for (int i=0;i<len;i++) {
    if(s[i]==')') sumNext++; 
  }
  int pos=-1;
  for (int i=0;i<=len;i++) {
    if(sumPre==sumNext) {
      pos=i;
      break;
    }
    if(s[i]=='(') {
      ++sumPre;
    }else{
      --sumNext;
    }
  }
  vector<int> a;
  for (int i=0;i<cut;i++) {
    if (s[i]=='(') {
      a.push_back(i);
    }
  }
  for (int i=pos;i<len;i++) {
    if (s[i]==')') {
      a.push_back(i);
    }
  }
  if (pos.empty()) {
    cout<<0<<endl;
  } else {
    cout<<1<<endl;
    cout<<a.size()<<endl;
    for (int i=0;i<a.size();i++) {
      if (i>0) cout<<" ";
      cout << pos[i] + 1;
    }
    cout<<endl;
  }
  return 0;
}

题解:
有两个变量一个记录 “(” 的数量,另一个记录 “)” 的数量。
先遍历一遍数组,记录 “)” 的数量总共有多少。
然后再一次遍历数组,从左往右,如果是 “(” sumPre就+1,如果是 “)” sumNext的数量就-1;"(" 与剩下的 ")"的数量相等的时候,就break;易得知,一整个数组里只有一个位置是这样的,之后只要遍历前一部分找 “(” ,遍历后一部分找 “)” 。
至于为什么这样就不会超过1次操作呢?因为数量相等,所以就算前一部分有多余,也只剩下 “)”,后一部分只剩下 “(”,
对于这种)))))))(((((,肯定不用继续操作了

实话实说也不知是怎么想到的,恕我愚钝了~~~

发布了62 篇原创文章 · 获赞 0 · 访问量 671

猜你喜欢

转载自blog.csdn.net/weixin_44745441/article/details/104655191