noip模拟79
A. F
签到题,然而我死了,自己想得太复杂.
A_code
#include<bits/stdc++.h>
using namespace std;
namespace BSS {
#define ll long long
#define ull unsigned ll
#define lf double
#define lbt(x) ((x)&(-(x)))
#define mp(x,y) make_pair(x,y)
#define lb lower_bound
#define ub upper_bound
#define Fill(x,y) memset(x,y,sizeof x)
#define Copy(x,y) memcpy(x,y,sizeof x)
#define File(x) freopen(#x".in","r",stdin),freopen(#x".out","w",stdout)
inline ll read() {
ll w=0; bool cit=1; char ch;
while(!isdigit(ch=getchar())) if(ch=='-') cit=0;
while(isdigit(ch)) w=(w<<3)+(w<<1)+(ch^48),ch=getchar();
return cit?w:-w;
}
} using namespace BSS;
const ll N=1e3+21,mod=998244353;
ll m,n,ts,ans,cnt;
ll vis[N],head[N];
bitset<N> bit[N];
struct I { ll u,v,nxt; } e[N*N];
auto add=[](ll u,ll v)->void{
e[++ts].u=u,e[ts].v=v,e[ts].nxt=head[u];
head[u]=ts;
};
auto ksm=[](ll a,ll b,ll c)->ll{
ll w=1; a%=c;
for(;b;b>>=1,a=a*a%c) if(b&1) w=w*a%c;
return w%c;
};
void bfs(){
queue<ll> que; ll u,v;
for(ll i=1;i<=n;i++) que.push(i),vis[i]=1;
while(que.size()){
u=que.front(),que.pop();
for(ll i=head[u];i;i=e[i].nxt){
if((bit[v=e[i].v]&bit[u])==bit[u]) continue;
bit[v]|=bit[u];
if(!vis[v]) que.push(v);
vis[v]=1;
}
vis[u]=0;
}
}
signed main(){
File(f);
n=read(); char ch[N]; ll u,v,tmp;
for(ll i=1;i<=n;i++){
scanf("%s",ch+1); bit[i].set(i,1);
for(ll j=1;j<=n;j++) if(ch[j]=='1') bit[j].set(i,1),add(i,j);
}
bfs();
for(ll i=1;i<=n;i++){
ans=(ans+ksm(bit[i].count(),mod-2,mod))%mod;
}
printf("%lld\n",ans),exit(0);
}
B. S
\(Kmp\) 自动机的模板题.
B_code
#include<bits/stdc++.h>
using namespace std;
namespace BSS {
#define ll int
#define ull unsigned ll
#define lf double
#define lbt(x) ((x)&(-(x)))
#define mp(x,y) make_pair(x,y)
#define lb lower_bound
#define ub upper_bound
#define Fill(x,y) memset(x,y,sizeof x)
#define Copy(x,y) memcpy(x,y,sizeof x)
#define File(x) freopen(#x".in","r",stdin),freopen(#x".out","w",stdout)
inline ll read() {
ll w=0; bool cit=1; char ch;
while(!isdigit(ch=getchar())) if(ch=='-') cit=0;
while(isdigit(ch)) w=(w<<3)+(w<<1)+(ch^48),ch=getchar();
return cit?w:-w;
}
} using namespace BSS;
const ll N=8e3+21;
char ch[N];
ll m,n,ans;
ll s[N],t[N],fail[N],jmp[N];
ll f[N][N],nxt[N][27];
inline void ckmin(ll &x,ll y){ x=min(x,y); };
signed main(){
File(s);
ans=1e8;
scanf("%s",ch+1),n=strlen(ch+1);
for(ll i=1;i<=n;i++) s[i]=ch[i]-'a'+1;
scanf("%s",ch+1),m=strlen(ch+1);
for(ll i=1;i<=n;i++) t[i]=ch[i]-'a'+1;
for(ll i=2,j=0;i<=n;i++){
while(j and t[i]!=t[j+1]) j=fail[j];
j+=(t[i]==t[j+1]),fail[i]=j;
}
for(ll i=0;i<=m;i++){
for(ll j=1;j<=26;j++)
nxt[i][j]= (t[i+1]==j ? (i+1) : nxt[fail[i]][j]);
}
Fill(f,0x3f); ll x; f[0][0]=0;
for(ll i=0;i<n;i++){
for(ll j=0;j<m;j++){
ckmin(f[i+1][j],f[i][j]+1),ckmin(f[i+1][nxt[j][s[i+1]]],f[i][j]);
}
}
for(ll i=0;i<m;i++) ans=min(ans,f[n][i]);
printf("%d\n",ans),exit(0);
}
C.「NOIP2013」华容道
比较牛逼的一道题.
暴力的思想就是每次枚举空白和指定位置的相对位置,然后深搜宽搜都能写.
考虑如何减少对于一些无用状态的枚举,发现空白只有挪动到指定位置的旁边的时候指定才能动.
于是可以预处理.
C_code
#include<bits/stdc++.h>
using namespace std;
namespace BSS
{
#define ll int
#define ull unsigned ll
#define lf double
#define lbt(x) ((x)&(-(x)))
#define mp(x,y) make_pair(x,y)
#define lb lower_bound
#define ub upper_bound
#define Fill(x,y) memset(x,y,sizeof x)
#define Copy(x,y) memcpy(x,y,sizeof x)
#define File(x) freopen(#x".in","r",stdin),freopen(#x".out","w",stdout)
inline ll read() {
ll w=0; bool cit=1; char ch;
while(!isdigit(ch=getchar())) if(ch=='-') cit=0;
while(isdigit(ch)) w=(w<<3)+(w<<1)+(ch^48),ch=getchar();
return cit?w:-w;
}
} using namespace BSS;
const ll N=32;
bool cs[N][N];
bool in[N][N][4];
ll m,n,kx,ky,sx,sy,ex,ey,ops,ans;
ll f[N][N];
ll st[N][N][4];
ll dis[N][N][4][N][N];
ll dx[4]={1,-1,0,0};
ll dy[4]={0,0,1,-1};
struct I{
ll x,y,d,dis;
I(){}
I(ll x,ll y,ll dis,ll d) : x(x),y(y),dis(dis),d(d) {}
};
queue<I> que;
inline void ckmin(ll &x,ll y){ x=min(x,y); }
auto bfs=[](ll x,ll y,ll d)->void{
if((!cs[x][y]) or (!cs[x+dx[d]][y+dy[d]])) return ;
cs[x+dx[d]][y+dy[d]]=0,dis[x][y][d][x][y]=0;
while(que.size()) que.pop(); I u; ll nx,ny;
for(que.push(I(x,y,0,0));que.size();){
u=que.front(),que.pop();
for(ll i=0;i<4;i++){
nx=u.x+dx[i],ny=u.y+dy[i];
if(dis[x][y][d][nx][ny]==-1 and cs[nx][ny]){
dis[x][y][d][nx][ny]=u.dis+1;
que.push(I(nx,ny,dis[x][y][d][nx][ny],0));
}
}
}
cs[x+dx[d]][y+dy[d]]=1;
};
inline void PreWork(){
Fill(dis,-1);
for(ll i=1;i<=n;i++){
for(ll j=1;j<=m;j++)
for(ll k=0;k<4;k++) bfs(i,j,k);
}
}
inline void Work(){
if(sx==ex and sy==ey) return puts("0"),void();
if((!cs[sx][sy]) or (!cs[ex][ey])) return puts("-1"),void();
Fill(st,0x3f),Fill(f,-1),f[kx][ky]=0,cs[sx][sy]=0;
while(que.size()) que.pop(); I u; ll nx,ny,nd,tmpdis;
for(que.push(I(kx,ky,0,0));que.size();){
u=que.front(),que.pop();
for(ll i=0;i<4;i++){
nx=u.x+dx[i],ny=u.y+dy[i];
if(cs[nx][ny] and f[nx][ny]==-1)
f[nx][ny]=u.dis+1,que.push(I(nx,ny,f[nx][ny],0));
}
}
cs[sx][sy]=1;
for(ll i=0;i<4;i++){
nx=sx+dx[i],ny=sy+dy[i];
if(f[nx][ny]==-1) continue;
que.push(I(sx,sy,f[nx][ny],i));
st[sx][sy][i]=f[nx][ny],in[sx][sy][i]=1;
}
while(que.size()){
u=que.front(),que.pop(); in[u.x][u.y][u.d]=0;
nx=u.x+dx[u.d],ny=u.y+dy[u.d],nd=u.d^1;
if(st[u.x][u.y][u.d]<st[nx][ny][nd]){
st[nx][ny][nd]=st[u.x][u.y][u.d]+1;
if(!in[nx][ny][nd]) que.push(I(nx,ny,st[nx][ny][nd],nd));
}
for(ll i=0;i<4;i++){
if(i==u.d) continue;
tmpdis=dis[nx][ny][nd][u.x+dx[i]][u.y+dy[i]];
if(tmpdis==-1 or st[u.x][u.y][u.d]+tmpdis>=st[u.x][u.y][i]) continue;
st[u.x][u.y][i]=st[u.x][u.y][u.d]+tmpdis;
if(!in[u.x][u.y][i]) que.push(I(u.x,u.y,st[u.x][u.y][i],i));
}
}
ans=min(st[ex][ey][0],st[ex][ey][1]),ckmin(ans,min(st[ex][ey][2],st[ex][ey][3]));
printf("%d\n",ans==0x3f3f3f3f ? -1 : ans );
}
signed main(){
File(y);
n=read(),m=read(),ops=read();
for(ll i=1;i<=n;i++){
for(ll j=1;j<=m;j++) cs[i][j]=read();
}
PreWork();
while(ops--)
kx=read(),ky=read(),sx=read(),sy=read(),ex=read(),ey=read(),Work();
exit(0);
}
D. O
拉格朗日插值,鸽了.

浙公网安备 33010602011771号