链接:https://ac.nowcoder.com/acm/contest/11213
目录
链接:https://ac.nowcoder.com/acm/contest/11213
B---最短串
给定2个由小写字母和问号组成的字符串a与b,问号代表你想要的任何字符。
请你找出最短的字符串s,要求s包含a和b两个字符串,你只需要输出s的长度即可。
模板:
判断B串是否为A串的子串:(可以直接使用)
bool judge(const string &a,const string &b)
{
int i,j;
if(a.length()<b.length())return false;
for(i=0;i<a.length();i++){
for(j=0;j<b.length();j++){
if(a[i+j]!=b[j])
break; // 字符不相等,退出
}
if(j==b.length()) // 达到了b.length,说明字符全部相等
return true;
}
return false;
}
思路:
求最短串长度,先判断以a为后缀时的长度,再判断以b为后缀时的长度,取最短长度即可。有?号的地方直接视为相同即可。
AC代码:
#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
const int INF = 0x3f3f3f3f;
const LL mod = 1e9 + 7;
const int N = 100005;
int cal(string s, string t) {//以t作为后缀
int res = s.size() + t.size();//res--s,t串总长度,答案的最大值
for (int i = 0; i < s.size(); i++) {
int ok = 1;
for (int j = 0; j < t.size() && i + j < s.size(); j++) {
if (t[j] == s[i + j] || t[j] == '?' || s[i + j] == '?');
else {
ok = 0;
break;
}
}
if (ok) {//如果t串为s串的子串,从某部分开始全部一样
res = i + max(t.size(), s.size() - i);//则答案res为s的前缀(s与t不同的部分)
//加上max(t.size(), s.size() - i)
break;
}
}
return res;
}
int main() {
string s, t;
cin >> s >> t;
cout << min(cal(s, t), cal(t, s)) << endl;
return 0;
}
C:杨辉三角(数学题,推出公式即可过)
小F对杨辉三角颇有研究,他把杨辉三角第n行的数提出来,从左到右分别为a[0],a[1],...,a[n−1]。
现在他想知道的值是多少,答案对99824353取模。
思路:
推出数学公式值为(n-1)*n*2^(n-3);由于n比较大,直接用pow会超时,用快速幂求解此公式。
AC代码:
#include<iostream>
#include<cmath>
using namespace std;
typedef long long ll;
const int N = 1e6 + 5;
const int mod = 99824353;
ll f[N];
ll n, m;
ll fp(ll a, ll n)
{
ll ans = 1;
ll base = a % mod;
while (n)
{
if (n & 1) ans = ans * base % mod;
base = base * base % mod;
n >>= 1;
}
return ans % mod;
}
int main()
{
ios::sync_with_stdio(false);
cin.tie(0), cout.tie(0);
while (cin >> n)
{
if (n == 1) cout << 0 << endl;
else if (n == 2) cout << 1 << endl;
else
{
m = n - 1;
cout << m % mod * (m + 1) % mod * fp(2, m - 2) % mod << endl;
}
}
return 0;
}
I:四面楚歌
在游戏中,因为一次错误的决断,你的士兵被敌方实行围剿。为了挽回人员损失,你不得不开启金手指暂停敌方士兵的移动,从而尽量让自己的士兵能成功突围。
已知地图是一块n×m的区域,每块格子有以下几种类型:
.:表示此处为一块空地。
1:表示此处有敌方士兵,不许通过。因为开启了金手指,所以敌方士兵不会移动。
0:表示此处有我方士兵。
现规定我方士兵只能进行上/下/左/右四个方向的移动,只要某个士兵移动出了地图边界,那么就算该士兵突围成功。请问能有多少士兵成功突围。
思路:
一道搜索的简单题,DFS,BFS都可以过,对搜索题不太熟,所以好好补了一下这个题,直接看代码。
AC代码:
#include<bits/stdc++.h>
using namespace std;
int n,m;
int dx[]={0,0,-1,1};//上下左右
int dy[]={1,-1,0,0};
char a[1010][1010];
int cnt=0;
int flag[1010][1010];
void dfs(int x,int y)//还没太看懂,看懂了以后回来补
{//如果该点为士兵或者该点已突围出去或者该点的flag==1,满足就返回函数
if(a[x][y]=='1' || x<0 || x>n+1 || y<0 || y>m+1 || flag[x][y]) //全部不成立就不返回
return ;
//否则定flag=1
flag[x][y]=1;
for(int i=0;i<4;i++)
{//向上下左右四个方向搜索
dfs(x+dx[i],y+dy[i]);
}
}
int main()
{
memset(a,'.',sizeof(a));//全部初始化为空地 .代表空地
cin>>n>>m;//输入区域大小
for(int i=1;i<=n;i++)//从1开始
{
for(int j=1;j<=m;j++)
{
cin>>a[i][j];
}
}
dfs(0,0);//从起点开始搜索
for(int i=1;i<=n;i++) //从1开始
{
for(int j=1;j<=m;j++)
{
if(a[i][j]=='0' && flag[i][j])
{
cnt++;
}
}
}
cout<<cnt;
}
写在后面的话:第二篇博客,第一篇题解,暑假集训快没有学习方向了,把以前比赛没写好的题补一补,开始加油写题解。