ABC378(DEF)
D
题意:
搜索长度为k的不同的路径
const int dx[]={1,-1,0,0};
const int dy[]={0,0,1,-1};
int n,m,k;
char g[20][20];
int vis[20][20];
int ans=0;
int res=0;
int dfs(int x,int y,int t){
if(t==k)return 1;
vis[x][y]=1;
int res=0;
for(int i=0;i<4;i++){
int nx=x+dx[i],ny=y+dy[i];
if(nx<1||nx>n||ny<1||ny>m)continue;
if(vis[nx][ny]||g[nx][ny]=='#')continue;
res+=dfs(nx,ny,t+1);
}
vis[x][y]=0;
return res;
// return max(res,1);
}
void solve(){
cin>>n>>m>>k;
rep(i,1,n){
rep(j,1,m)cin>>g[i][j];
}
rep(i,1,n){
rep(j,1,m){
if(g[i][j]=='.'){
ans+=dfs(i,j,0);
}
}
}
cout<<ans<<endl;
}
E
题意:求解所给式子的大小
思路:
区间和[l,r]可转化为前缀和Sr-Sl-1
由于mod m,所以当sr<sl-1时需要+m再取模m
通过树状数组输出在r前面且前缀和大于r的前缀和的数量
注意树状数组要向右偏移一位,因为前缀和取模m后可能为0
int n,m;
int bit[maxn];
int lowbit(int x){return x&-x;}
void add(int p,int x){
// if(p==0)return;
while(p<=m){
bit[p]+=x;
p+=lowbit(p);
}
}
int query(int p){
int res=0;
while(p){
res+=bit[p];
p-=lowbit(p);
}
return res;
}
void solve(){
cin>>n>>m;
vector<int>a(n+1);
rep(i,1,n){
cin>>a[i];
}
vector<int>pre(n+1);
vector<int>g(n+1);
rep(i,1,n){
pre[i]=(pre[i-1]+a[i])%m;
}
rep(i,1,n){
g[i]=g[i-1]+pre[i];
}
vector<int>x(n+1);
rep(i,1,n){
add(pre[i]+1,1);
x[i]=i-query(pre[i]+1);
}
int ans=0;
for(int r=1;r<=n;r++){
ans+=r*pre[r]-g[r-1]+x[r]*m;
}
cout<<ans<<endl;
}
F
题意:给定一颗树,求连接一条边后成环且环上每点度数为3的图的数量
思路:DFS求解
相当于求解一个度数为3的链并且挑选两个链上连接的度数为2的点的组合数大小
vector<int>e[maxn];
int deg[maxn];
int vis[maxn];
//n*(n-1)/2
int dfs(int u){
if(vis[u])return 0;
int res=0;
vis[u]=1;
for(int v:e[u]){
if(deg[v]==2){
res++;
}else if(deg[v]==3){
res+=dfs(v);
}
}
return res;
}
void solve(){
int n;cin>>n;
rep(i,1,n-1){
int u,v;
cin>>u>>v;
deg[u]++;deg[v]++;
e[u].pb(v);e[v].pb(u);
}
int ans=0;
rep(i,1,n){
int res=0;
if(deg[i]==3&&!vis[i]){
res+=dfs(i);
}
ans+=res*(res-1)/2;
}
cout<<ans<<endl;
}

浙公网安备 33010602011771号