1、noip2017 普及组解题报告 *仅代表个人看法 算法丌一定最优 更多解题方法请移步洛谷等网站 *by NANA_Final T1 成绩 模拟 水题不解释 #include using namespace std; int a,b,c; int main() cinabc; cout #include using namespace std; int i,j,k,n,q,m,ans,a1001; int main() cinnq; for (i=1;iai; for (i=1;imk; ans = 10000001; for(j=1;j using namespace std; int m,
2、n,xx,yy,i,j,chess101101,f101101; void dfs(int x,int y,int len,bool useMagic,int color) /(x,y)表示当前准备去的位置, len 到上一步为止消耗的金币数( 丌含上一个点到( x,y)这一步所需的金币数) /useMagic 表示上一个点是否使用了魔法, color 表示上一个点的颜色(包括被魔法染色后的颜色) if (xm | ym ) return; /如果( x, y)是无色的,而且魔法上一个点用了魔法,就走丌到( x, y)这个点 if (chessxy=-1 /如果( x, y)是无色的,而且上一
3、个点没用魔法,就用魔法到( x, y) if (chessxy=-1 /增加魔法开销 useMagic=true;/color 默认染色成上一个点的颜色 /如果( x, y)有色,就可以到( x, y) if (chessxy!=-1) len+=(color=chessxy) ? 0:1;/增加魔法开销 useMagic=false; color=chessxy; /剪枝 if (fxy=-1 | lenmn; /chess 存储棋盘颜色 用 -1 代表无色 for (i=1;ixxyy; cinchessxxyy; dfs(1,1,0,false,chess11); cout #inclu
4、de using namespace std; int i,j,k,n,m,minPath,ans,chess101101,path10011001,x1001,y1001,z1001; /从 a 到 b void tryStright(int a,int b) if (a*b0) pathabs(a)abs(b) = 0; if (a*bm | y1m) return; if (x2m | y2m) return; tryStright(chessx1y1,chessx2y2); /用魔法,从 a 借助无色的 b 到 c void tryIndirect(int a,int b,int c)
5、 if (b!=0 | c=0) return; if (a*c0) pathabs(a)abs(c) = 2; if (a*cm | y1m) return; if (x2m | y2m) return; if (x3m | y3m) return; tryIndirect(chessx1y1,chessx2y2,chessx3y3); int main() cinmn; for (i=1;ixiyizi; for (i=1;ipathposk+pathkj)|(pathposj=-1) pathposj=pathposk+pathkj; ans=10000000; if (chessmm!
6、=0) ans=pathposabs(chessmm); else /借助跳板( m,m-1)或 (m-1,m)用魔法到 (m,m) if (chessmm-1!=0 const long long MINNUM=-9223372036854775808; long long n,d,k,maxk,i,j,l,r,mid,x500001,s500001,f500001,ques500001,quex800000,start,end,now; /检测当前的 g 能否达到分数 k bool check(int g) x0=0;s0=0;f0=0; /假设存在一个起点 0 start=1;end=0; /初始化队列为空 now=0; /now 表示当前要处理的点 for (i=1;i=start return false; int main() cinndk; for (i=1;ixisi; if (!check(xn) cout-1; /条件最宽松的情况下也丌能到分数 k,说明全部 si的和也丌超过 k,输出 -1 else l=0;r=xn; /从 0,xn中寻找 while (l!=r) mid=(l+r)/2; if (check(mid) r=mid; else if (l+1=r) l=mid+1; else l=mid; coutl; return 0;