1、贪吃蛇(CJOJ P2185)
第一眼是深搜,于是考场上写了个啥都不加的。。50分
#include<cstdio>
#include<algorithm>
using namespace std;
bool Z[22][22];
struct data{int x,y;}que[1001];
int hd=1,tl,ans=1000000000;
inline int gi(){
int x=0;char ch=getchar();
while(ch<'0'||ch>'9')ch=getchar();
while(ch>='0'&&ch<='9')x=x*10+ch-'0',ch=getchar();
return x;
}
int n,m;
const int X[]={23333,-1,0,1,0},Y[]={333333,0,-1,0,1};
inline void dfs(int x,int y,int b){
if(b>ans)return;
if(x==1&&y==1){ans=b;return;}
int tx=que[hd].x,ty=que[hd].y;
for(int i=1;i<=4;i++){
register int nx=que[tl-1].x+X[i],ny=que[tl-1].y+Y[i];
if(!Z[nx][ny]){
Z[tx][ty]=0,Z[nx][ny]=1;
que[tl]=(data){nx,ny};
++hd,++tl;
dfs(nx,ny,b+1);
Z[tx][ty]=1,Z[nx][ny]=0;
--hd,--tl;
}
}
}
int main(){
n=gi(),m=gi();
for(int i=1;i<=m;i++)Z[0][i]=Z[n+1][i]=1;
for(int i=1;i<=n;i++)Z[i][0]=Z[i][m+1]=1;
int a,b,l=gi(),k;
tl=l+1;
for(int i=l;i;i--){
que[i].x=gi(),que[i].y=gi();
Z[que[i].x][que[i].y]=1;
}
k=gi();
while(k--)a=gi(),b=gi(),Z[a][b]=1;
dfs(que[l].x,que[l].y,0);
printf("%d\n",ans);
return 0;
}
经ZJO大神指点,写了个迭代,再加剪枝。。90分。。第9个点S也过不去
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cstdlib>
using namespace std;
bool Z[22][22];
struct data{int x,y;}que[1001];
int hd=1,tl;
inline int gi(){
int x=0;char ch=getchar();
while(ch<'0'||ch>'9')ch=getchar();
while(ch>='0'&&ch<='9')x=x*10+ch-'0',ch=getchar();
return x;
}
int n,m,flag=0;
const int X[]={23333,-1,0,1,0},Y[]={333333,0,-1,0,1};
inline void dfs(int x,int y,int b,int maxx){
if(b==maxx){
if(x==1&&y==1){
printf("%d\n",maxx);
exit(0);
}
return;
}
if(b+x+y-2>maxx)return;//剪枝
int tx=que[hd].x,ty=que[hd].y;
for(int i=1;i<=4;i++){
register int nx=que[tl-1].x+X[i],ny=que[tl-1].y+Y[i];
if(!Z[nx][ny]){
Z[tx][ty]=0,Z[nx][ny]=1;
que[tl]=(data){nx,ny};
++hd,++tl;
dfs(nx,ny,b+1,maxx);
Z[tx][ty]=1,Z[nx][ny]=0;
--hd,--tl;
}
}
}
int main(){
n=gi(),m=gi();
for(int i=1;i<=m;i++)Z[0][i]=Z[n+1][i]=1;
for(int i=1;i<=n;i++)Z[i][0]=Z[i][m+1]=1;
int a,b,l=gi(),k;
tl=l+1;
for(int i=l;i;i--){
que[i].x=gi(),que[i].y=gi();
Z[que[i].x][que[i].y]=1;
}
k=gi();
while(k--)a=gi(),b=gi(),Z[a][b]=1;
int i;
for(i=1;;i++)dfs(que[l].x,que[l].y,0,i);
return 0;
}
再加个SPFA与处理出最短距离,再用它来剪枝,过了。。。但个人分析有时也会被卡的没答案,然而数据水还是A了(以下为丑的一比的代码)
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cstdlib>
#include<queue>
using namespace std;
int Z[22][22];
struct data{int x,y;}que[1001];
int hd=1,tl,hehe [22][22];
inline int gi(){
int x=0;char ch=getchar();
while(ch<'0'||ch>'9')ch=getchar();
while(ch>='0'&&ch<='9')x=x*10+ch-'0',ch=getchar();
return x;
}
int n,m,flag=0;
const int X[]={23333,-1,0,1,0},Y[]={333333,0,-1,0,1};
void spfa(){
int que[500],in[22][22]={0};
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
hehe[i][j]=10000000;
hehe[1][1]=0;
in[1][1]=1;
que[1]=0;
int hd=1,tl=2;
while(hd^tl){
int fx=que[hd]/m+1,fy=que[hd]%m+1;
for(int i=1;i<=4;i++){
int nx=fx+X[i],ny=fy+Y[i];
if(Z[nx][ny]!=2&&hehe[nx][ny]>hehe[fx][fy]+1){
hehe[nx][ny]=hehe[fx][fy]+1;
if(!in[nx][ny]){
in[nx][ny]=1;
que[tl++]=(nx-1)*m+ny-1;
if(tl==450)tl=1;
}
}
}
hd++;
if(hd==450)hd=1;
in[fx][fy]=0;
}
}
inline void dfs(int x,int y,int b,int maxx){
if(b==maxx){
if(x==1&&y==1){
printf("%d\n",maxx);
exit(0);
}
return;
}
if(b+hehe[x][y]>maxx)return;
int tx=que[hd].x,ty=que[hd].y;
for(int i=1;i<=4;i++){
register int nx=que[tl-1].x+X[i],ny=que[tl-1].y+Y[i];
if(!Z[nx][ny]){
Z[tx][ty]=0,Z[nx][ny]=1;
que[tl]=(data){nx,ny};
++hd,++tl;
dfs(nx,ny,b+1,maxx);
Z[tx][ty]=1,Z[nx][ny]=0;
--hd,--tl;
}
}
}
int main(){
n=gi(),m=gi();
for(int i=1;i<=m;i++)Z[0][i]=Z[n+1][i]=1;
for(int i=1;i<=n;i++)Z[i][0]=Z[i][m+1]=1;
int a,b,l=gi(),k;
tl=l+1;
for(int i=l;i;i--){
que[i].x=gi(),que[i].y=gi();
Z[que[i].x][que[i].y]=1;
}
k=gi();
while(k--)a=gi(),b=gi(),Z[a][b]=2;
spfa();
int i;
for(i=1;;i++)dfs(que[l].x,que[l].y,0,i);
return 0;
}
2、晨跑路径(CJOJ P1956)
第一眼水题,写了Tarjan
第二眼暴力,果断删了Tarjan,枚举删每一条边(还Tarjan,What a Sabi I am!)
然而还是WA了,链式前向星没乘2。。。(What a Sabi I am!还有为什么这段代码震惊了整个机房)
AC:
#include<cstdio>
#include<algorithm>
#include<cstring>
#define t (dis[i])
using namespace std;
const int maxn=2010,maxm=8010<<1;
int fir[maxn],nxt[maxm],dis[maxm];
int n,m;
inline void adde(int fr,int to,int id){nxt[id]=fir[fr],fir[fr]=id,dis[id]=to;}
inline int gi(){
int x=0;char ch=getchar();
while(ch<'0'||ch>'9')ch=getchar();
while(ch>='0'&&ch<='9')x=x*10+ch-'0',ch=getchar();
return x;
}
bool vis[maxn];
int ans[maxn],Ans=0;
inline void dfs(int now){
vis[now]=1;
for(int i=fir[now];i;i=nxt[i])
if(!vis[t])dfs(t);
}
int main(){
n=gi(),m=gi();
int a,b;
for(int i=1;i<=m;i++)
a=gi(),b=gi(),adde(a,b,i<<1),adde(b,a,i<<1|1);
for(int i=2;i<n;i++){
memset(vis,0,sizeof vis);
vis[i]=1;
dfs(1);
if(vis[n]==0)ans[++Ans]=i;
}
printf("%d\n",Ans);
for(int i=1;i<=Ans;i++)printf("%d ",ans[i]);
return 0;
}
3、任务安排(CJOJ P1371)
额啊啊啊DP啊各种单调队列斜率优化什么的都来啦
感谢QT666大神指点,有了这段代码
#include<cstdio>
#include<algorithm>
#define C(j,i) (F[j]+s*(W[n]-W[j])+T[i]*(W[i]-W[j]))
using namespace std;
inline int gi(){
int x=0;char ch=getchar();
while(ch<'0'||ch>'9')ch=getchar();
while(ch>='0'&&ch<='9')x=x*10+ch-'0',ch=getchar();
return x;
}
int T[5011],W[5011];
long long F[5011];
int n,s;
int main(){
#ifndef xzz
#endif
n=gi(),s=gi();
for(int i=1;i<=n;i++)
T[i]=T[i-1]+gi(),W[i]=W[i-1]+gi();
for(int i=1;i<=n;i++){
F[i]=C(0,i);
for(int j=1;j<i;j++)
F[i]=min(F[i],C(j,i));
}
printf("%lld",F[n]);
return 0;
}