题目
链接:https://ac.nowcoder.com/acm/contest/9700/A
来源:牛客网题目描述
给定一个长度为 n 数列,判断其是否为“牛”的,是则输出“YES”,否则输出“NO”。
一个数列是“牛”的,当且仅当其满足以下三个条件中至少一个:
1、这个数列是等差数列
2、这个数列是等比数列
3、这个数列是等模数列。
等差数列和等比数列的定义如果不清楚建议百度或重上小学(划掉),等模数列的定义是:对于任意相邻两数,后一个对前一个取模后的值均相等。
输入描述:
第一行一个整数 n。 第二行 n 个整数,分别表示这个数列的值。
输出描述:
一行,一个单词“YES”或“NO”(不含引号)。
示例1
输入
[复制](javascript:void(0)😉
5 1 2 3 4 5
输出
[复制](javascript:void(0)😉
YES
说明
此数列为等差数列。
示例2
输入
[复制](javascript:void(0)😉
3 5 7 16
输出
[复制](javascript:void(0)😉
YES
说明
此数列为等模数列。
备注:
3 <= n <= 10^5,1 <= 数列中的每个数<=10^9
分析
模拟了事
代码
#include <iostream>
using namespace std;
const int N = 100010;
int n;
double a[N];
bool x, y, z;
int main() {
cin >> n;
cin >> a[0] >> a[1];
for (int i = 2; i < n; i ++ ) {
scanf("%lf", &a[i]);
//判断是否为等差
int d = a[1] - a[0];
if (a[i] - a[i - 1] != d) x = true;
//判断是否为等比
double q = a[1] / a[0];
if (a[i] / a[i - 1] != q) y = true;
//判断时候为等模
int m = (int)a[1] % (int)a[0];
if ((int)a[i] % (int)a[i - 1] != m) z = true;
}
if (!x || !y || !z) puts("YES") ;
else puts("NO");
return 0;
}
CCA的字符串
题目
链接:https://ac.nowcoder.com/acm/contest/9700/B
来源:牛客网题目描述
给定一个仅由大写字母和小写字母组成的字符串。
一个字符串是“牛”的,当且仅当其有一个子串为“NowCoder”(区分大小写)。
问给定字符串有多少个子串是“牛”的。
输入描述:
一行,一个字符串。
输出描述:
一行,一个数表示答案。
示例1
输入
[复制](javascript:void(0)😉
NowCoderNowCode
输出
[复制](javascript:void(0)😉
8
备注:
字符串长度<=10^5
分析
考虑代表元计数法,把每个字串的贡献记录在最靠左的
NowCoder
上。设[i, i + 7]这一段是NowCoder
,last为上一个NowCoder
左端点的位置,可取得左端点范围是[last + 1, i],右端点是[i + 7, n],对答案得贡献即(i - last) * (n - (i + 7) + 1)
代码
#include <bits/stdc++.h>
using namespace std;
int main()
{
string a;
cin>>a;
long long ans=0;
long long t=0;
int last=-1;
/*
我就好奇了,这个代码是怎么AC的???
*/
for(int i=0;i<a.length();i++)
{
if(a[i]=='N'&&a[i+1]=='o'&&a[i+2]=='w'&&a[i+3]=='C'&&a[i+4]=='o'&&a[i+5]=='d'&&a[i+6]=='e'&&a[i+7]=='r')
{
//cout << a[i] << "-----------" << ans << endl;
ans=ans+(i-last)*(a.length()-i-7);
last=i;
}
}
printf("%lld\n",ans);
}
CCA的矩阵
题目
链接:https://ac.nowcoder.com/acm/contest/9700/C
来源:牛客网题目描述
很久很久以后的某一天,老鼠泛滥成灾啦!
有某一个 n×n 的矩形内布满了老鼠,具体来说,(i,j) 上有 w(i,j)只老鼠。
万幸的是,你有一个 k×k 的锤子,一锤子砸下去可以把它覆盖到的所有老鼠清除。
遗憾的是,这个锤子只能斜着锤,形象地说,对于一个 3×3 的锤子,它能覆盖到的区域如下:
- - * - -
- * * * -
* * * * *
- * * * -
- - * - -
你想知道,自己一锤子砸下去,最多能清除多少只老鼠。
输入描述:
第一行两个数 n和k 。 之后的 n 行,每行 n 个数,第 i 行 第 j 个数表示在矩形的这个位置有多少只老鼠。
输出描述:
一行,一个整数表示最多能清除的老鼠数量。
示例1
输入
[复制](javascript:void(0)😉
3 2 0 1 1 1 0 1 0 1 0
输出
[复制](javascript:void(0)😉
4
备注:
n <= 2000 , k <= min(n, 100),每个点的老鼠数量 <= 10^9
分析
墨染空大佬的代码,我是还没分析出来,留到以后水平高了后再来做
墨染空大佬的代码
/*
*@author SunLakeWalk
*/
#include <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>
#include <cmath>
#include <vector>
#include <queue>
#include <deque>
#include <stack>
#include <map>
#include <unordered_map>
#include <set>
//#pragma GCC optimize(2)
//#pragma GCC optimize(3, "Ofast", "inlin")
using namespace std;
#define ios ios::sync_with_stdio(false) , cin.tie(0)
#define x first
#define y second
typedef long long LL;
typedef pair<int, int> PII;
const int N = 2010, INF = 0x3f3f3f3f, mod = 1e9 + 7;
const double eps = 1e-6, pi = acos(-1);
int n, k;
LL s[N][N], a[N][N], b[N][N], c[N][N];
LL ans;
/*
我们可以发现这是一个斜着的前缀和,这里是墨染空巨佬的做法。
通过观察,发现菱形区域可以看作斜着的正方形。
正方形里面包含了k个k长度的序列和k-1个k-1长度的序列。
我们分别用a和b数组来存储斜的前缀和。
斜着的前缀和只由它的(i-1,j-1)转移过来的
*/
void work() {
scanf("%d%d", &n, &k);
for (int i = 1; i <= n; i ++ )
for (int j = 1; j <= n; j ++ )
scanf("%lld", &s[i][j]);
/*
让s存入数据,让a记录长度为k的,斜前缀和
让b记录长度为k - 1的,斜前缀和
让c记录以(i,j)为最下面的那个点所在的菱形的长宽为k的斜前缀和,即我们的答案
*/
for (int i = 1; i <= n; i ++ )
for (int j = 1; j <= n; j ++ ) {
a[i][j] = a[i - 1][j - 1] + s[i][j];
if (i > k && j > k) a[i][j] -= s[i - k][j - k];//维护长度为k
b[i][j] = b[i - 1][j - 1] + s[i][j];
if (i > k - 1 && j > k - 1) b[i][j] -= s[i - k + 1][j - k + 1];//维护长度为k-1
}
for (int i = 1; i <= n; i ++ )
for (int j = 1; j <= n; j ++ ) {
/*
*/
c[i][j] = c[i - 1][j + 1] + a[i][j] + b[i - 1][j] - a[i - k][j + k] - b[i - k][j + k - 1];
if (j + k - 1 <= n && j - k + 1 >= 1 && i - (2 * k - 1) + 1 >= 1) ans = max(ans, c[i][j]);
}
cout << ans << endl;
}
int main() {
work();
return 0;
}
多次打印墨染空大佬的代码
/*
*@author SunLakeWalk
*/
#include <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>
#include <cmath>
#include <vector>
#include <queue>
#include <deque>
#include <stack>
#include <map>
#include <unordered_map>
#include <set>
//#pragma GCC optimize(2)
//#pragma GCC optimize(3, "Ofast", "inlin")
using namespace std;
#define ios ios::sync_with_stdio(false) , cin.tie(0)
#define x first
#define y second
typedef long long LL;
typedef pair<int, int> PII;
const int N = 100010, INF = 0x3f3f3f3f, mod = 1e9 + 7;
const double eps = 1e-6, pi = acos(-1);
int n = 5, k = 2;
int a[100][100], s[100][100], b[100][100], c[100][100];
int ans = 0;
void print(int a[100][100]) {
for (int i = 1; i <= n; i ++ ) {
for (int j = 1; j <= n; j ++ )
printf("%d ", a[i][j]);
puts("");
}
puts("----------------------");
}
void work() {
for (int i = 1; i <= n; i ++ )
for (int j = 1; j <= n; j ++ )
s[i][j] = i;
print(s);
for (int i = 1; i <= n; i ++ )
for (int j = 1; j <= n; j ++ ) {
a[i][j] = s[i][j] + a[i - 1][j - 1];
if (i > k && j > k) a[i][j] -= s[i - k][j - k];
}
print(a);
for (int i = 1; i <= n; i ++ )
for (int j = 1; j <= n; j ++ ) {
b[i][j] = s[i][j] + b[i - 1][j - 1];
if (i > k - 1 && j > k - 1) b[i][j] -= s[i - k + 1][j - k + 1];
}
print(b);
for (int i = 1; i <= n; i ++ )
for (int j = 1; j <= n; j ++ ) {
c[i][j] = c[i - 1][j + 1] + a[i][j] + b[i - 1][j] - a[i - k][j + k] - b[i - k][j + k - 1];
if (j + k - 1 <= n && j - k + 1 >= 1 && i - (2 * k - 1) + 1 >= 1) ans = max(ans, c[i][j]);
}
print(c);
cout << ans << endl;
}
int main() {
work();
return 0;
}