牛客小白月赛44
A.深渊水妖
题意:找到所有极长的不严格上升段,并找出它们当中右端点权值 - 左端点权值最大的那些个段,输出端点坐标。
绷不住啦,比赛时没有看明白题目wa了呜呜┭┮﹏┭┮
思路:最上上升子序列模型,双指针,找出区间两点最大的权值,然后在遍历一遍输出满足要求的区间左右端点值。
代码:
#include<bits/stdc++.h>
using namespace std;
const int N=1e5+10;
int n,a[N];
void solve()
{
cin>>n;
for(int i=1;i<=n;i++) cin>>a[i];
int maxn=0;
for(int i=1;i<=n;i++){
int j=i;
while(j+1<=n&&a[j+1]>=a[j]) j++;
maxn=max(maxn,a[j]-a[i]);
i=j;
}
for(int i=1;i<=n;i++){
int j=i;
while(j+1<=n&&a[j+1]>=a[j]) j++;
if(a[j]-a[i]==maxn) cout<<i<<' '<<j<<' ';
i=j;
}
cout<<endl;
}
int main()
{
int _;
cin>>_;
while(_--){
solve();
}
return 0;
}
B.顽皮恶魔
题意:
你的庄园是一块 n×m的草坪。
现在有一些格子是普通植物 P,有一些格子是萝卜保护伞 ∗,有一些格子是僵尸 Z。(已经在格子上的僵尸不会吃掉植物或移动)
tip:萝卜保护伞可以保护周围 3×3 的植物,即一个位于位置 (x,y)(x,y)(x,y) 的萝卜保护伞可以保护位于 (x±1,y),(x,y±1),(x±1,y±1)以及自身九个格子上的植物。
现在你想知道,对于这样一块给定的草坪,假设有无穷多个飞贼,能够偷走最多数量的植物是多少。
思路:枚举每个点,找到没有被萝卜保护伞保护的植物即可。ps:每次清空数组不能用memset(g,0,sizeof(g)),会导致TLE,因为这个T了好几次,难顶。
代码:
#include<bits/stdc++.h>
#define IOS std::ios::sync_with_stdio(false);cin.tie(0);cout.tie(0)
#define INF 0x3f3f3f3f
using namespace std;
typedef long long LL;
typedef pair<int,int> PII;
typedef pair<double,double> PDD;
const int N=1e3+10;
int n,m;
int t;
int dx[8] = {-1, -1, -1, 0, 1, 1, 1, 0};
int dy[8] = {-1, 0, 1, 1, 1, 0, -1, -1};
int main()
{
cin>>t;
while(t--)
{
char g[N][N];
int ans=0;
cin>>n>>m;
for(int i=0;i<=n+1;i++)
for(int j=0;j<=m+1;j++)
g[i][j]='Z';
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
{
cin>>g[i][j];
if(g[i][j]=='P')
ans++;
}
for(int i=1;i<=n;i++)
{
for(int j=1;j<=m;j++)
{
if(g[i][j]=='*')
{
for(int k=0;k<8;k++)
{
int x=i+dx[k],y=j+dy[k];
if(g[x][y]=='P'){
ans--;
g[x][y]='Z';
}
}
}
}
}
cout<<ans<<endl;
}
return 0;
}
C.绝命沙虫
题意:
初始时你的手上有 NNN 元 RMB。
交易规则如下:
给定 N,M,请回答你最后获得的消费经验是多少。
思路:按照给定规则进行模拟即可,需要注意到精度问题,比赛时粗心看到一位小数就没有考虑精度被卡QwQ.
代码:
#include<bits/stdc++.h>
#define IOS std::ios::sync_with_stdio(false);cin.tie(0);cout.tie(0)
#define INF 0x3f3f3f3f
using namespace std;
typedef long long LL;
typedef pair<int,int> PII;
typedef pair<double,double> PDD;
const int N=1e3+10;
int n;
double m;
int t;
int dx[8]={1,0,-1,0,1,1,-1,-1},dy[8]={0,1,0,-1,1,-1,1,-1};
int main()
{
cin>>t;
while(t--)
{
LL ans=0;
cin>>n>>m;
LL red=0,green=0,temp;
temp=100*m-100;
LL now=n;
while(now)
{
red+=now*100;
green+=min(10000LL,temp*now);
now=0;
now+=red/200;
ans+=red/10;
ans+=green/10;
red=0;
green=0;
}
cout<<ans<<endl;
}
return 0;
}
D.丛林木马
题意:
众所周知,如果给你两个数 a,b 要你计算 a×b=c 的值,你就知道要这么做:把每一位相乘并且乘上它们的 10^k 然后相加,其中 k 表示对应数位的幂次。
有一次,可怜的 ZM 不小心把“相乘”中的所有乘法运算都算成了加法,她想让你帮忙算算,这样算出来的结果是多少?
思路:看样例不难得出,结果是a每位的值 x b的长度加上b每位的值 x a的长度其实就是a x b的长度+b x a的长度。
代码:
//属于是给我写复杂了QAQ
#include<bits/stdc++.h>
using namespace std;
const int MOD=998244353;
typedef long long LL;
LL quick_power(LL a,LL b,LL p)
{
LL ans=1;
while(b)
{
if(b&1) ans=(ans%p*a%p)%p;
b>>=1;
a=(a%p*a%p)%p;
}
return ans%p;
}
int main()
{
int t;
cin>>t;
while(t--)
{
string a,b;
cin>>a>>b;
LL ans=0;
LL la=a.size(),lb=b.size();
for(LL i=0;i<la;i++)
ans=(ans%MOD+quick_power(10, la-i-1, MOD)*(a[i]-'0')%MOD*lb%MOD)%MOD;
for(LL i=0;i<lb;i++)
ans=(ans%MOD+quick_power(10, lb-i-1, MOD)*(b[i]-'0')%MOD*la%MOD)%MOD;
cout<<ans%MOD<<endl;
}
}
#python版本
t=int(input())
for i in range(t):
a,b=input().split()
m=min(len(a),len(b))
print((int(a)*len(b)+int(b)*len(a))%998244353)
E.变异蛮牛
题意:
给定一棵根为 1,且是黑点的有根树。
每个白点相邻所有的点都是黑点,每个黑点相邻所有的点都是白点。换句话说,你可以从根结点开始,按照深度对每个点黑白染色。
现在对于一条两个端点分别是 u,v 的链,定义其长度为:包含的黑点个数 - 包含的白点个数。
请你数一数 长度最大 的链的个数。
思路:
本题要求树上有多少个起点和终点均为黑点的路径。
设黑点数为cnt,dfs求黑点的数量,最终答案便为cnt+cnt*(cnt-1)/2;
代码:
#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
const int N=2e5+10;
vector<int> e[N];
int n,u,v;
LL cnt;
void dfs(int u,int fa,int deep)
{
if(deep&1) cnt++;
for(int i=0;i<e[u].size();i++){
int v=e[u][i];
if(v==fa) continue;
dfs(v,u,deep+1);
}
}
void solve()
{
cin>>n;
for(int i=1;i<=n;i++) e[i].clear();
cnt=0;
for(int i=1;i<n;i++){
cin>>u>>v;
e[u].push_back(v);
e[v].push_back(u);
}
dfs(1,0,1);
cout<<cnt+(cnt-1)*cnt/2<<endl;
}
int main()
{
int _;
cin>>_;
while(_--){
solve();
}
return 0;
}

浙公网安备 33010602011771号