2025 National Invitational of CCPC (Zhengzhou), 2025 CCPC Henan Provincial Collegiate Programming Contest
D.2025
M.川陀航空学院
J.Ring Trick
H.树论函数
结论题,所有点连通
G.直径与最大独立集
F.幻形之路
起点能到达的点b设为1,终点能到达的点b设为2
现在整个图最多有三块,按顺序一块1一块0一块2,走的时候分别判断
#include<bits/stdc++.h>
using namespace std;
const int N=1010;
int n,m;int dx[4]={1,0,-1,0};int dy[4]={0,1,0,-1};
char a[N][N];
int b[N][N];
int d[N][N];
/*
10
5 5
.....
.....
.....
.....
.....
4 7
..#####
#######
..###..
.......
3 7
.######
#######
######.
*/
signed main(){
std::ios::sync_with_stdio(false);
int T;cin>>T;
while(T--){
cin>>n>>m;
for(int i=1;i<=n;i++){
string str;cin>>str;
for(int j=1;j<=m;j++){
a[i][j]=str[j-1];
}
}
for(int i=1;i<=n;i++)for(int j=1;j<=m;j++){b[i][j]=0;}
queue<pair<int,int>> q;q.push({1,1});b[1][1]=1;
while(!q.empty()){
auto [x,y]=q.front();q.pop();
for(int k=0;k<4;k++){
int tx=x+dx[k];int ty=y+dy[k];
if(tx<=0||tx>=n+1||ty<=0||ty>=m+1)continue;
if(a[tx][ty]=='#')continue;if(b[tx][ty]==1)continue;
b[tx][ty]=1;q.push({tx,ty});
}
}
q.push({n,m});b[n][m]=2;
while(!q.empty()){
auto [x,y]=q.front();q.pop();
for(int k=0;k<4;k++){
int tx=x+dx[k];int ty=y+dy[k];
if(tx<=0||tx>=n+1||ty<=0||ty>=m+1)continue;
if(a[tx][ty]=='#')continue;if(b[tx][ty]==2)continue;
b[tx][ty]=2;q.push({tx,ty});
}
}
deque<pair<int,int>> dq;
int ans=0x3f3f3f3f;
for(int i=1;i<=n;i++)for(int j=1;j<=m;j++)d[i][j]=-1;
dq.push_front({1,1});d[1][1]=0;
while(!dq.empty()){
auto [x,y]=dq.front();dq.pop_front();
// cout<<x<<" "<<y<<'\n';
for(int k=0;k<4;k++){
int tx=x+dx[k];int ty=y+dy[k];
if(tx<=0||tx>=n+1||ty<=0||ty>=m+1)continue;
if(d[tx][ty]!=-1)continue;
if(b[tx][ty]==1)d[tx][ty]=d[x][y];
else if(b[tx][ty]==0)d[tx][ty]=d[x][y]+1;
else if(b[tx][ty]==2){d[tx][ty]=d[x][y];
ans=min(ans,d[x][y]);
}
if(d[tx][ty]==d[x][y])
dq.push_front({tx,ty});
else dq.push_back({tx,ty});
}
}
cout<<ans<<'\n';
}
}
E.双生魔咒
经典结论:前缀相同的字符串在字符串中连续排列,dfn连续
某个前缀出现cnt[p]次,由基本不等式,可以去到的最大价值是(cnt[p]/2)*(cnt[p]+1)/2
可以dfn奇数作为"引",偶数作为"根",就可以达到这个最大价值
#include<iostream>
using namespace std;
#define int long long
const int N=200010;
int tr[N][30];
int cnt[N];int idx=0;
void insertt(string str){
int p=0;
for(auto c:str){
if(!tr[p][c-'a'])tr[p][c-'a']=++idx;
p=tr[p][c-'a'];
cnt[p]++;
}
}
int main(){
std::ios::sync_with_stdio(false);
int T;T=1;
while(T--){
int n;cin>>n;
for(int i=1;i<=2*n;i++){
string str;cin>>str;insertt(str);
}
int ans=0;
for(int i=1;i<=idx;i++){
ans+=(cnt[i]/2)*((cnt[i]+1)/2);
}
cout<<ans<<'\n';
}
}

浙公网安备 33010602011771号