牛客小白月赛60_ACM/NOI/CSP/CCPC/ICPC算法编程高难度练习赛_牛客竞赛OJ
C小竹关禁闭
题目描述
妈妈成功将小竹救了出来,她觉得小竹实在是太笨了,决定关小竹一周禁闭。可是小竹哪里能忍受失去自由,他早就偷藏了一部手机用于联系你,请求你帮助他逃离。
你通过观察发现他房间内有 nnn 个可用于制成绳子的物品,第 iii 个的长度为 aia_iai 。当你使用第 iii 个物品制作绳子时,其右侧的 kkk 个物品(不含第iii个物品)就无法再被用于制作绳子 。最终,小竹用选择的物品制成绳子,绳子的长度是所选择物品的长度之和。
小竹想知道,他能制作的绳子长度最长为多少?
简单dp即可,dp[i] 表示 选到第i个物品为止所能凑出的最长绳子
#include<bits/stdc++.h>
using namespace std;
int n,k;
const int N=2010;
int a[N];
int dp[N];
int main()
{
ios::sync_with_stdio(false);
cin.tie(0),cout.tie(0);
cin>>n>>k;
for(int i=1;i<=n;i++)cin>>a[i];
for(int i=1;i<=n;i++)
{
int j=max(0,i-k-1);
dp[i]=max(dp[j]+a[i],dp[i-1]);
}
cout<<dp[n];
return 0;
}
D:游戏购买!
链接:登录—专业IT笔试面试备考平台_牛客网
来源:牛客网
小竹成功从家里逃了出来,他决定去小胖家避一避。但是小胖要求小竹带一个刺激度大于 xxx 的游戏才能去他家。
为了防止被妈妈或她的朋友发现,小竹不会在道路上行走,而是在建筑物与建筑物之间穿行。
街道表现为一个 n×mn \times mn×m 的网格,网格上只有两种建筑: 商店和住宅。商店可以通过而住宅无法通过。
小竹每次从当前所在网格可以行走到上下左右的网格中,但不能移动到网格的边界之外和别人的家中。正式的说,如果他在坐标为 (i,j)(i,j)(i,j) 的网格里,他可以选择 (i+1,j),(i,j+1),(i−1,j),(i,j−1)(i+1,j) , (i,j+1) , (i - 1,j) , (i,j-1)(i+1,j),(i,j+1),(i−1,j),(i,j−1) 四个方向行走。
在位置 (i,j)(i,j)(i,j) 上的商店有一个刺激度为 wi,jw_{i,j}wi,j 的游戏,小竹可以购买他所经过的商店中的游戏并带走。若 wi,jw_{i,j}wi,j 为 −1-1−1 则代表这个位置是个住宅,无法通过。
注意:小胖家以及小竹家均可以被通过。
假设相邻的建筑物的距离均为 111,小竹想知道带一个刺激度高于 xxx 的游戏去小胖家需要的最短距离是多少?如果这是不可能实现的,请输出 −1-1−1。
解法:从起点终点各BFS一次,然后枚举每个大于X的中转点即可
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<int,int> PII;
const int N=2010;
int n,m,x;
int sx,sy,ex,ey;
ll g[N][N];
int dist[N][N];
int dist1[N][N];
void bfs1()
{
int dx[]={1,0,-1,0};
int dy[]={0,-1,0,1};
queue<PII> q;
memset(dist1,-1,sizeof dist);
dist1[ex][ey]=0;
q.push({ex,ey});
while(!q.empty())
{
PII p=q.front();
q.pop();
int a=p.first,b=p.second;
for(int i=0;i<4;i++)
{
int sa=a+dx[i],sb=b+dy[i];
if(sa<1||sa>n||sb<1||sb>m)continue;
if(g[sa][sb]==-1||dist1[sa][sb]!=-1)continue;
dist1[sa][sb]=dist1[a][b]+1;
q.push({sa,sb});
}
}
}
int bfs()
{
int dx[]={1,0,-1,0};
int dy[]={0,-1,0,1};
queue<PII> q;
memset(dist,-1,sizeof dist);
q.push({sx,sy});
dist[sx][sy]=0;
while(!q.empty())
{
PII p=q.front();
q.pop();
int a=p.first,b=p.second;
for(int i=0;i<4;i++)
{
int sa=a+dx[i],sb=b+dy[i];
if(sa<1||sa>n||sb<1||sb>m)continue;
if(g[sa][sb]==-1||dist[sa][sb]!=-1)continue;
dist[sa][sb]=dist[a][b]+1;
q.push({sa,sb});
}
}
if(dist1[sx][sy]==-1)return -1;
int ans=0x3f3f3f3f;
for(int i=1;i<=n;i++)
{
for(int j=1;j<=m;j++)
{
if(g[i][j]>x&&dist[i][j]!=-1&&dist1[i][j]!=-1)
{
ans=min(ans,dist[i][j]+dist1[i][j]);
}
}
}
if(ans==0x3f3f3f3f)return -1;
return ans;
}
int main()
{
ios::sync_with_stdio(false);
cin.tie(0),cout.tie(0);
cin>>n>>m>>x;
cin>>sx>>sy>>ex>>ey;
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)cin>>g[i][j];
bfs1();
cout<<bfs();
return 0;
}
E 寻找小竹!
妈妈发现小竹逃走了,非常的气愤,她决定出去寻找小竹!和小竹不同的是,妈妈是道路上行走。
妈妈和小竹所在的城市有 nnn 个路口,n−1n-1n−1 条道路,并且保证任意两个路口互相联通。每个路口根据妈妈审美的不同都有一个优雅值,而如果两个相邻的路口的优雅值存在至少两个共同的质因子ppp和qqq(p≠qp\neq qp=q)则这两个相邻的路口就是共同优雅的。
妈妈将共同优雅联通块定义为:在城市中选取若干个路口,若这些路口们两两互相联通,且每两个相邻的路口都是共同优雅的,则该联通块称为共同优雅联通块。
注意:单独的一个路口也符合共同优雅联通块的定义。
妈妈想知道,整个城市的最大优雅联通块包含多少个路口。
解法:首先筛出所有合数,然后将每个质数的倍数也筛出来,因为题意为两个数必须含有两个不同的质因数,然后直接树形DP即可,在dfs的时候顺便更新一下答案
#include<bits/stdc++.h>
using namespace std;
const int N=1e6+10,M=N*2;
int n;
vector<int> primes;
bool st[(int)5e6+10];
struct node{
int to,nxt;
}edge[M];
int cnt;
int head[N];
int w[N];
int f[N];
int ans;
void add(int from,int to)
{
edge[cnt].to=to;
edge[cnt].nxt=head[from];
head[from]=cnt++;
}
void get_prime(int k)
{
for(int i=2;i<=k;i++)
{
if(!st[i])primes.push_back(i);
for(int j=0;primes[j]<=k/i;j++)
{
st[i*primes[j]]=true;
if(i%primes[j]==0)break;
}
}
}
int gcd(int a,int b)
{
return b?gcd(b,a%b):a;
}
void dfs(int u,int fa)
{
f[u]=1;
for(int i=head[u];~i;i=edge[i].nxt)
{
int v=edge[i].to;
if(v==fa)continue;
dfs(v,u);
if(st[gcd(w[u],w[v])])f[u]+=f[v];
}
ans=max(ans,f[u]);
}
int main()
{
ios::sync_with_stdio(false);
cin.tie(nullptr),cout.tie(nullptr);
memset(head,-1,sizeof head);
int m=5e6+1;
get_prime(m);
for(int i=0;i<(int)primes.size();i++)
{
for(int j=primes[i];j<=m/primes[i];j*=primes[i])st[j]=false;
}
cin>>n;
for(int i=1;i<=n;i++)cin>>w[i];
for(int i=0;i<n-1;i++)
{
int x,y;
cin>>x>>y;
add(x,y),add(y,x);
}
dfs(1,-1);
cout<<ans;
return 0;
}
代码更清晰一点点