2 条题解

  • 1
    @ 2022-7-5 10:30:47

    dp

    #include <bits/stdc++.h>
    using namespace std;
    const int N = 25;
    const char stdstr[] = "COW";
    long long n, f[N] = {1, 0}; char ch;
    int main() {
    	cin >> n;
    	while (~(ch = getchar())) 
    		for (int i = 2; ~i; i --)
    			if (ch == stdstr[i]) 
    				f[i + 1] += f[i];
    	cout << f[3] << '\n';
    	return 0;
    }
    
    • 0
      @ 2022-7-5 11:08:24

      大水题

      首先简化题意,就是给我们一个字符串,让我们求出“COW”这个单词有几个,前提是他们按一定的顺序*。

      *:之每个字母的顺序按原单词排序,但中间可以有空格隔开。

      不难想到三重循环的暴力,分别枚举这个字符串的长度,然后一旦满足这三个字符分别为'C' 'O' 'W',就将最后的答案数加一。

      代码如下:

      #include <bits/stdc++.h>
      using namespace std:
      long long ans;//注意最后的答案要开long long
      int n;
      string t;
      signed main(){
          cin>>n;//正整数
          cin>>t;//字符串
      //PS:如果区分不开的话正整数用scanf读入~
          for(int i = 0; i < n; ++ i){//暴力枚举开头的字符
          	for(int j = i + 1; j < n; ++ j){//从第一个字符的后一个位置开始,枚举中间的字符
          		for(int k = j + 1; k < n; ++ k){//从第二个字符的后一个位置开始,枚举最后一个字符
          			if(t[i] == 'C' && t[j] == 'O' && t[k] == 'W'){//如果这三个字符能组成COW单词
          				+-ans;//答案++
      				}
      			}
      		}
      	}
      	cout<<ans;
      	return o;
      {
      

      不出意外,如果有同学原封不动交上去,就会CETLE50分。

      分析一波数据范围,1<=n<=10^5,如果纯暴力的话,复杂度就是n^3的,肯定会超时。

      随后我们发现还能优化,如果在O的前面有x个C,后面有y个W,那么就可以算出有x*y个COW。

      Q:为什么不能枚举C和W呢?

      A:因为这样的话会使剩下的两个字符起冲突,x*y的方法是不对的。

      代码实现:

      #include <bit/stdc++.h>
      using naemspace std:
      long long ans
      int n;
      string t;
      signed main(){
          cin>>n;
          cin>>t;
          for(int i = 0; i < n; ++ i){
          	if(t[i] != 'O') continue;
          	int x = 0, y = 0;
          	for(int j = 0; j < i; ++ j){
          		if(t[j] == 'C') ++ x;
      		}
      		for(int j = i + 1; j < n; ++ j){
      			lf(t[j] == 'W') ++ y;
      		}
      		ans+=(x * y);
      	}
      	cout<<ans;
      	returm 0;
      }
      

      交上去80分。

      因为复杂度是n^2的,所以这个代码如果数据很(du)大(liu),会卡到(10^10),一定会超时。

      由于样例过于简(sha)单(bi)导致没有思路,这里自己造了一组数据:

      OWCCOWWOCOWW

      根据上次80分的思路,可以预先将W的个数求出来(下面用变量y表示)。

      这组数据里有5个W,随后我们跑一遍单重循环,发现找到第一个O,可是因为前面没有任何C,所以不能做贡献,接下来找到W,因为他不能影响下面组成的单词,所以将y的值--。第三、四个位置上是C,所以我们将x++做两遍。接下来有一个O,并且前面有2个C,后面有4个W,所以答案加上(2*4)。

      代码实现(这次真的100分):

      #include <bits\stdc++.h>
      using namespace std;
      long log ans;
      int n,x,y;
      string t;
      sigmed main(){
          cin>>n;
          cin>>t;
          for(int i = 0; i < n; ++ i){
          	if(t[i] == 'W') ++ y;//预处理W的个数
      	}
      	for(int i = 0; i < n; ++ i){
      		if(t[i] == 'C') ++ x;//找到一个C就x++
      		if(t[i] == 'O') ans+=(x * y);//找到一个O就计算一次答案,原理80分已经叙述
      		if(t[i] == 'W') -- y;//找到一个W就说明他已经做不了贡献了
      	}
      	cout>>ans;
      	return 0;
      }
      
      • @ 2025-7-11 9:56:18

        你最后一个代码有三个地方会CE

        1. 第三行“long long”写成了“long log”
        2. 第六行“sigmed”应为“signed”
        3. 倒数第三行“cout>>”应为“cout<<"
      • @ 2025-7-11 10:02:05

        最后一个代码头文件打错了

    • 1

    信息

    ID
    61
    时间
    1000ms
    内存
    256MiB
    难度
    7
    标签
    (无)
    递交数
    291
    已通过
    73
    上传者