牛客练习赛74AB

A CCA的数列

题目
链接:https://ac.nowcoder.com/acm/contest/9700/A
来源:牛客网

题目描述
给定一个长度为 n 数列,判断其是否为“牛”的,是则输出“YES”,否则输出“NO”。
一个数列是“牛”的,当且仅当其满足以下三个条件中至少一个:
1、这个数列是等差数列
2、这个数列是等比数列
3、这个数列是等模数列。
等差数列和等比数列的定义如果不清楚建议百度或重上小学(划掉),等模数列的定义是:对于任意相邻两数,后一个对前一个取模后的值均相等。
输入描述:
第一行一个整数 n。
第二行 n 个整数,分别表示这个数列的值。
输出描述:
一行,一个单词“YES”或“NO”(不含引号)。
示例1
输入
复制
5
1 2 3 4 5
输出
复制
YES
说明
此数列为等差数列。
示例2
输入
复制
3
5 7 16
输出
复制
YES
说明
此数列为等模数列。
备注:
3 <= n <= 10^5,1 <= 数列中的每个数<=10^9

题意
符合等比数列等差数列等mod数列就是“牛”的数列 问给定数列是否为牛数列

思路
直接比较即可,很坑的地方是 等比数列必须考虑到公比不是整数的情况,但是也不能用double存因为后面要取模

代码

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

const int maxn = 100000+100;

int a[maxn];
int main()
{
	int n;
	cin>>n;
	for(int i=1;i<=n;i++) cin>>a[i];
	int f1 = 1,f2 = 1,f3 = 1;
	int b = a[2] - a[1];
	for(int i=3;i<=n;i++)
	{
		if(a[i]-a[i-1]!=b)
		{
			f1 = 0;
			break;
		}
	}
	if(f1)
	return cout<<"YES",0;
	double c = a[2]*1.0/a[1]*1.0;
//	cout<<c<<endl;
	for(int i=3;i<=n;i++)
	{
		if(1.0*a[i]/a[i-1]*1.0!=c)
		{
//			cout<<i<<" "<<1.0*a[i]/1.0*a[i-1]<<endl;
			f2 = 0;
			break;
		}
	}
	if(f2)
	return cout<<"YES",0;
	int d = a[2]%a[1];
	for(int i=3;i<=n;i++)
	{
		if(a[i]%a[i-1]!=d)
		{
			f3 = 0;
			break;
		}
	}
	if(f3)
	return cout<<"YES",0;
	cout<<"NO";
} 

B CCA的字符串

题目
链接:https://ac.nowcoder.com/acm/contest/9700/B
来源:牛客网

题目描述
给定一个仅由大写字母和小写字母组成的字符串。
一个字符串是“牛”的,当且仅当其有一个子串为“NowCoder”(区分大小写)。
问给定字符串有多少个子串是“牛”的。
输入描述:
一行,一个字符串。
输出描述:
一行,一个数表示答案。
示例1
输入
复制
NowCoderNowCode
输出
复制
8
备注:
字符串长度<=10^5

题意
给定一个字符串 定义“牛”的字符串当且仅当其有一个子串为“NowCoder”

这里非常需要注意的是 当且仅当有一个子串为“NowCoder”的意思是,只要有一个子串是“NowCoder”就可以,两个连着的也行!!!打比赛的时候吃了语文的亏还行,题面也改了三次 从子串改成子序列又改成子串 有点迷惑

思路1
查询当前下一个“NowCoder”的位置,用len - position - 8 + 1 (-8的意思是去掉“NowCoder”这一段,+1代表着算上“NowCoder”自己) 再减去当前的位置,由于i是往后递增的,所以position是递减的,这时候由于前面算过了 所以要减去i

代码1

#include <bits/stdc++.h>
using namespace std;
 
int main()
{
    string s;
    cin>>s;
    int len = s.size();
    int cnt = 0;
    long long ans = 0;
    for(int i=0;i<len-7;i++)
    {
//        string now = "";
//        for(int j=i;j<i+8;j++)
//        now += s[j];
        long long cnt = s.substr(i).find("NowCoder");
//        cout<<cnt<<endl;
        if(cnt == -1) break;
            ans += len - 8 + 1 - i - cnt;
//        cout<<ans<<endl;
    }
    cout<<ans;
    return 0;
}

/*
NowCoderNowCoder
*/

思路2

学习牛客网上同仁写的 并加深了理解
考虑代表元计数法,把每个子串的贡献记录在最靠左的 NowCoder 上。

\([i, i + 7]\) 这一段是 NowCoder,lastlast 为上一个 NowCoder 左端点的位置,可取的左端点范围是 \([last + 1, i]\),右端点是 \([i + 7, n]\),对答案的贡献即 \((i - last) \times (n - (i + 7) + 1)\)

代码2

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

typedef long long ll;
 
int main()
{
    string s;
    cin>>s;
    s = "+" + s;
    ll len = s.size();
    len--;
    ll cnt = 0;
    ll ans = 0;
    ll last = 0;
//    cout<<len<<endl;
    for(int i=1;i<=len-7;i++)
    {
        string now = "";
        for(int j=i;j<i+8;j++)
        now += s[j];
        if(now=="NowCoder")
        {
//        	cout<<i<<endl;
        	ans += (i - last) * (len - (i+7) + 1LL);
        	last = i;
		}
    }
    cout<<ans;
    return 0;
}

/*
NowCoderNowCoder
*/
posted @ 2020-12-20 22:43  墨墨墨小白iiy💭💡🎈  阅读(155)  评论(0编辑  收藏  举报