hey_left 9 Codeforces Round 871 (Div. 4) 续
E.
连通块的搜索
debug:用不上回溯,把连通块的贡献全部加起来
#include <bits/stdc++.h>
using namespace std;
int n,m;
int g[1010][1010];
bool vis[1010][1010];
int ma,tmp;
int dx[5]={-1,1,0,0};
int dy[5]={0,0,1,-1};
void dfs(int x,int y){
tmp+=g[x][y];
//cout<<"x="<<x<<' '<<"y="<<y<<'\n';
//cout<<"sum="<<sum<<'\n';
//tmp+=g[x][y];
vis[x][y]=true;
for(int i=0;i<4;i++){
int xx=x+dx[i],yy=y+dy[i];
if(xx<1||xx>n||yy<1||yy>m)continue;
if(vis[xx][yy]||g[xx][yy]==0)continue;
//cout<<"xx="<<xx<<' '<<"yy="<<yy<<'\n';
dfs(xx,yy);
}
}
void solve(){
cin>>n>>m;
for(int i=1;i<=n;i++){
for(int j=1;j<=m;j++){
cin>>g[i][j];
vis[i][j]=false;
}
}
// for(int i=1;i<=n;i++){
// for(int j=1;j<=m;j++){
// cout<<g[i][j]<<' ';
// }
// cout<<'\n';
// }
ma=0;
for(int i=1;i<=n;i++){
for(int j=1;j<=m;j++){
if(vis[i][j]||g[i][j]==0)continue;
// cout<<"**********************"<<'\n';
tmp=0;
// cout<<"i="<<i<<' '<<"j="<<j<<'\n';
dfs(i,j);
ma=max(ma,tmp);
}
}
cout<<ma<<'\n';
}
signed main(){
int hey_left=1;
cin>>hey_left;
while(hey_left--){
solve();
}
}
F.
先特判只有2个顶点的时候的答案是1 0
剩下的分为直径为2和4的情况
直径为2:
此时只有x,y=0
先找一个叶子节点
再从叶子节点深搜,深度为1一定是中心节点,中心节点关联边的数量就是x
直径为4:
先找一个叶子节点
再从叶子节点深搜,深度为3的节点一定是二级分支,这个点关联边的数量-1就是y
因为深搜记录了父节点,而这个点的父节点就是中心节点,中心节点关联边的数量就是x
(搜深度为3是因为深度为3的节点一定是二级分支,深度为2的有可能还是三级分支,不一定是中心节点)
debug:深搜一定要带父节点,然后遇到父节点跳过,不然会报错
#include <bits/stdc++.h>
using namespace std;
int n,m;
vector<int>g[210];
int leave,d;
int xx,yy;
void find_leave(int u,int fa){
if(g[u].size()==1){
leave=u;
return ;
}
for(int i=0;i<g[u].size();i++){
int y=g[u][i];
if(y==fa)continue;
find_leave(y,u);
}
}
void find_d(int u,int dep,int fa){
if(dep>d){
d=dep;
}
for(int i=0;i<g[u].size();i++){
int y=g[u][i];
if(y==fa)continue;
find_d(y,dep+1,u);
}
}
void find_x(int u,int fa,int dep){
if(dep==1){
xx=g[u].size();
return ;
}
for(int i=0;i<g[u].size();i++){
int y=g[u][i];
if(y==fa)continue;
find_x(y,u,dep+1);
}
}
void find_y(int u,int fa,int dep){
if(dep==3){
xx=g[fa].size();
yy=g[u].size()-1;
return ;
}
for(int i=0;i<g[u].size();i++){
int y=g[u][i];
if(y==fa)continue;
find_y(y,u,dep+1);
}
}
void solve(){
cin>>n>>m;
for(int i=1;i<=n;i++)g[i].clear();
for(int i=0,u,v;i<m;i++){
cin>>u>>v;
g[u].push_back(v);
g[v].push_back(u);
}
if(n==2){
cout<<"1 0"<<'\n';
return ;
}
find_leave(1,0);
xx=yy=0;
find_d(leave,0,0);
//cout<<"d="<<d<<'\n';
if(d==2){
find_x(leave,0,0);
cout<<xx<<' '<<0<<'\n';
}else if(d==4){
find_y(leave,0,0);
cout<<xx<<' '<<yy<<'\n';
}
}
signed main(){
int hey_left=1;
cin>>hey_left;
while(hey_left--){
solve();
}
}
G.
有点像动态规划入门的三角形
但不全是,要减去重复的一个
然后因为这个没做出来
#include <bits/stdc++.h>
using namespace std;
#define int unsigned long long
int a[2050][2050];
int b[2050][2050];
map<int,int>mp;
void solve(){
int n;cin>>n;
cout<<mp[n]<<'\n';
}
signed main(){
int hey_left=1;
cin>>hey_left;
int x=1;
for(int i=1;i<=2023;i++){
for(int j=1;j<=i;j++){
a[i][j]=x*x;
if(i>1){
b[i][j]=b[i-1][j]+b[i-1][j-1]+a[i][j]-b[i-2][j-1];
}else b[i][j]=1;
mp[x]=b[i][j];
//cout<<"x="<<x<<' '<<"mp[x]="<<mp[x]<<' ';
x++;
}
//cout<<'\n';
}
while(hey_left--){
solve();
}
}