任凭风浪起

img

牛客周赛 Round 26

小红的整数操作

直接取余进行判断即可

因为取余之后相等之后意味着二者一定能通过加减这个数字得到,而一个数字减实际上等价于一个数字加。

因此完全可以。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
#include<bits/stdc++.h>
using namespace std;
int main()
{
ios::sync_with_stdio(0);
cin.tie(0),cout.tie(0);
int m,n;
cin>>m>>n;
map<int,int>ms;
for(int i=0;i<m;i++){
int x;
cin>>x;
ms[x%n]++;
}
int ans=0;
for(auto x:ms)
{
// cout<<x.second<<endl;
ans=max(ans,x.second);
}
cout<<ans<<endl;


return 0;
}

小红的01串

容易猜到只要两个都是奇数就一定不行

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
#include<bits/stdc++.h>
using namespace std;
const int N = 2e5 + 9;
typedef long long ll;
typedef unsigned long long ull;
const ll mod = 998244353;
int q;
string s;
void solve()
{
cin >> q;
while(q--)
{
cin >> s;
int n = s.size();
s = " " + s;
int x = 0, y = 0;
for( int i = 1; i <= n; i++ )
{
if(s[i] == '1')
{
x++;
}else
{
y++;
}
}
if(x % 2 == 0 || y % 2 == 0)
cout << "Yes\n";
else
cout << "No\n";
}
}
int main()
{
ios::sync_with_stdio(false);
cin.tie(0),cout.tie(0);
int T = 1;
while(T--)
{
solve();
}
return 0;
}

小红闯沼泽地

用优先队列寻路跑一遍最短路即可

优先队列第一个是距离

第二个则是x坐标和y坐标

每次取出来最小的,并用他来更新

不过这里的更新和图不一样

只需要遍历移动数组即可

如果前后不等,就加二

不然加一即可

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
#include<bits/stdc++.h>
using namespace std;
typedef pair<int,pair<int,int>> PPII;
int ma[2010][2010];
int n,m;
int dist[2010][2010];
int st[2010][2010];
int dx[3]={0,0,1};
int dy[3]={-1,1,0};
void dijkstra(){
memset(dist,0x3f,sizeof dist);
//初始化为无穷
dist[1][1]=0;
//初始点为0
priority_queue<PPII,vector<PPII>,greater<PPII>>h;
//最小堆
h.push({0,{1,1}});
while(h.size()){
auto tt=h.top();
//取出堆顶
h.pop();
//弹出堆顶
int dis=tt.first;
//距离
int x=tt.second.first;
//x坐标
int y=tt.second.second;
//y坐标
if(st[x][y]) continue;
st[x][y]=1;
for(int i=0;i<3;i++){
int xx=x+dx[i];
int yy=y+dy[i];
if(xx<1||xx>n||yy<1||y>m) continue;
if(ma[x][y]!=ma[xx][yy]&&dist[xx][yy]>dis+2){
dist[xx][yy]=dis+2;
h.push({dist[xx][yy],{xx,yy}});
//放入
}
if(ma[xx][yy]==ma[x][y]&&dist[xx][yy]>dis+1){
dist[xx][yy]=dis+1;
h.push({dist[xx][yy],{xx,yy}});
//放入
}
}
}
}

int main(){
cin>>n>>m;
for(int i=1;i<=n;i++){
for(int j=1;j<=m;j++){
cin>>ma[i][j];
//输入
}
}
dijkstra();
cout<<dist[n][m];
//输出
return 0;
}

小红的漂亮串(二)

维护两个DP数组: f[i]表示长度 i的字符串中一个red也没有的种类数; g[i]表示长度 i的字符串中有且只有一个red的种类数;

对于f[i]:

不选字符d,即没有构成一个新red的可能,除了d还有25个字母, 那么f[i] = f[i-1]$*$25。 选字符串d,即有构成red的可能,它的前两个字符就不能是re,否则不符合“一个red也没有”。所以此时f[i] = f[i-1] -f[i-3]。 综上,f [ i ] = f [ i − 1 ] ∗ 26 − f[ i − 3 ] 对于g[i]:

不选字符d,g[i] = g[i-1]$*$25 选字符d: 若之前一个red也没有,且前两个字符为re,那就正好有一个red,g[i] = f[i-3] 若之前已经有一个red,那他的前两个字符不能是re。g[i] = g[i-1] - g[i-3] 综上,g [ i ] = g [ i − 1 ] ∗ 26 − g[ i − 3 ] + f [ i − 3 ]

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#include<bits/stdc++.h>
using namespace std;
using ll = long long;
int main() {
std::ios::sync_with_stdio(false);
std::cin.tie(nullptr);
std::cout.tie(nullptr);
int n;
std::cin >> n;
std::vector<ll> f(n + 1), g(n + 1);
f[0] = 1;
f[1] = 26;
f[2] = 26 * 26;
ll ans = 26 * 26;
const int mod = 1e9 + 7;
for (int i = 3; i <= n; ++i) {
ans = ans * 26 % mod;
f[i] = (f[i - 1] * 26 - f[i - 3]) % mod;
g[i] = (g[i - 1] * 26 + f[i - 3] - g[i - 3]) % mod;
}
std::cout << ((ans - f[n] - g[n]) % mod + mod) % mod;
return 0;
}