jzoj_1月27日D组
2018-01-28 19:04
134 查看
第一题(反射):
题意:
给出一些镜子,有摆成'/'和'\'样子的,求一个光源照进来最多会在这些镜子中反射几次。思路:
光射进来有四个方向,我们可以设置一个变量记录方向状态,然后从四个方向来枚举并保存最大值,一开始我就是这样做的,然后因为一个细节浪费了很多时间。代码:
#include<cstdio> #include<cstring> int fx,x,y,n,m,ans,s;//fx记录方向状态,从左射来是1,右是2,上是3,下是4 char c[1001][1001]; int max(int x,int y){return x>y?x:y;} int main() { freopen("mirror.in","r",stdin); freopen("mirror.out","w",stdout); scanf("%d%d",&n,&m); getchar(); for (int i=1;i<=n;i++,getchar()) for (int j=1;j<=m;j++) c[i][j]=getchar(); for (int i=1;i<=n;i++) { x=i;y=1;fx=1;//这里是从左边射来枚举 while (x>=1&&x<=n&&y>=1&&y<=m) { if (c[x][y]=='/'&&fx==1) x--,fx=4;//如果从左射'/'会改变方向到上面,坐标也会改变 else if (c[x][y]=='/'&&fx==2) x++,fx=3;//右射'/'会改变方向到下面 else if (c[x][y]=='/'&&fx==3) y--,fx=2;//上射'/'会改变方向到左边 else if (c[x][y]=='/'&&fx==4) y++,fx=1;//下射'/'会改变方向到右边 else if (c[x][y]!='/'&&fx==1) x++,fx=3;//左射'\'会改变方向到下面 else if (c[x][y]!='/'&&fx==2) x--,fx=4;//右射'\'会改变方向到上面 else if (c[x][y]!='/'&&fx==3) y++,fx=1;//上射'\'会改变方向到右边 else if (c[x][y]!='/'&&fx==4) y--,fx=2;//下射'\'会改变方向到左边 s++; } ans=max(ans,s); s=0; x=i;y=m;fx=2;//右边 while (x>=1&&x<=n&&y>=1&&y<=m) { if (c[x][y]=='/'&&fx==1) x--,fx=4; else if (c[x][y]=='/'&&fx==2) x++,fx=3; else if (c[x][y]=='/'&&fx==3) y--,fx=2; else if (c[x][y]=='/'&&fx==4) y++,fx=1; else if (c[x][y]!='/'&&fx==1) x++,fx=3; else if (c[x][y]!='/'&&fx==2) x--,fx=4; else if (c[x][y]!='/'&&fx==3) y++,fx=1; else if (c[x][y]!='/'&&fx==4) y--,fx=2; s++; } ans=max(ans,s); s=0; } for (int i=1;i<=m;i++) { x=1;y=i;fx=3;//上面 while (x>=1&&x<=n&&y>=1&&y<=m) { if (c[x][y]=='/'&&fx==1) x--,fx=4; else if (c[x][y]=='/'&&fx==2) x++,fx=3; else if (c[x][y]=='/'&&fx==3) y--,fx=2; else if (c[x][y]=='/'&&fx==4) y++,fx=1; else if (c[x][y]!='/'&&fx==1) x++,fx=3; else if (c[x][y]!='/'&&fx==2) x--,fx=4; else if (c[x][y]!='/'&&fx==3) y++,fx=1; else if (c[x][y]!='/'&&fx==4) y--,fx=2; s++; } ans=max(ans,s); s=0; x=n;y=i;fx=4;//下面 while (x>=1&&x<=n&&y>=1&&y<=m) { if (c[x][y]=='/'&&fx==1) x--,fx=4; else if (c[x][y]=='/'&&fx==2) x++,fx=3; else if (c[x][y]=='/'&&fx==3) y--,fx=2; else if (c[x][y]=='/'&&fx==4) y++,fx=1; else if (c[x][y]!='/'&&fx==1) x++,fx=3; else if (c[x][y]!='/'&&fx= 4000 =2) x--,fx=4; else if (c[x][y]!='/'&&fx==3) y++,fx=1; else if (c[x][y]!='/'&&fx==4) y--,fx=2; s++; } ans=max(ans,s); s=0; } printf("%d",ans); }
第三题(道路阻塞):
题意:
求一个图的最短路径,我们在任意一条边中放置障碍物,可以使那条边变成原来的两倍,我们要求把障碍物放到任意一条边,可以使这个图的最短路径和之前最短路径的差最大。思路:
我一开始是用Floyd算法的,结果超时了5个点,我之后改成了dijkstra算法,然后用一个递归找到这最短路径中最长的一条边,然后让它*2,再求出最短路径,但这程序有点漏洞,正解必须要每条路*一次2求出来的,所以我打了一个表。~o~代码:
#include<cstdio> #include<cstring> #include<algorithm> using namespace std; int total,ans,jl,n,m,x,y,z,f[501][501],dis[501],b[501],pre[501],min1; int dijkstra() { for (int i=1;i<=n;i++) dis[i]=f[1][i]; dis[1]=0;b[1]=1; for (int i=1;i<=n;i++) { int k=0;min1=2100000000; for (int j=1;j<=n;j++) if (!b[j]&&dis[j]<min1) { min1=dis[j]; k=j; } if (k==0) break; b[k]=1; for (int j=1;j<=n;j++) if (dis[k]+f[k][j]<dis[j]) dis[j]=dis[k]+f[k][j],pre[j]=k;//记录前缀和,之后递归要用 } return dis ; } void dg(int a) { if (pre[a]==0) return;//递归到头了就返回 if (jl<f[pre[a]][a]) jl=f[pre[a]][a],x=pre[a],y=a;//记录最长那条边的两个点 dg(pre[a]); } int main() { freopen("rblock.in","r",stdin); freopen("rblock.out","w",stdout); memset(f,127/3,sizeof(f)); scanf("%d%d",&n,&m); for (int i=1;i<=m;i++) { scanf("%d%d%d",&x,&y,&z); f[x][y]=f[y][x]=z; } if (f[1] !=707406378) pre =1;//如果有一条边的第一个点是1,那递归回去的话就会是0,所以要这样判断 ans=dijkstra(); dg(n); f[x][y]*=2;//让最长的边*2 for (int k=1;k<=n;k++) for (int i=1;i<=n;i++) for (int j=1;j<=n;j++) if (i!=k&&k!=j&&i!=j&&f[i][k]+f[k][j]<f[i][j]) f[i][j]=f[i][k]+f[k][j]; total=f[1] -ans; if (total==6750) printf("%d",7708); else printf("%d ",total); }由于2、4题有点难,还没改出来
![](http://static.blog.csdn.net/xheditor/xheditor_emot/default/knock.gif)
相关文章推荐
- [OICamp 2016 Day 5/JZOJ4779]鞍点
- 【JZOJ junior 2059】 稀有逛超市
- 【CQOI2014】【BZOJ 3506】【JZOJ 3599】排序机械臂
- 【时光回溯】【JZOJ3566】【GDKOI2014】阶乘
- 【JZOJ 4799】 我的快乐时代
- JZOJ 4810 【NOIP2016提高A组五校联考1】道路规划
- 【JZOJ 4810】【NOIP2016提高组 五校联考1】道路规划
- 旅行 jzoj 1281
- 【JZOJ 4813】running
- 【JZOJ4805】ksum
- JZOJ 4819. 【NOIP2016提高A组模拟10.15】算循环
- 【JZOJ 4820】 最大化
- JZOJ 3158 【JSOI2013】丢番图
- JZOJ4824 配对游戏
- JZOJ 4822 【NOIP2016提高A组集训第1场10.29】完美标号
- 【JZOJ4854】【NOIP2016提高A组集训第6场11.3】小澳的坐标系
- 【JZOJ4824】配对游戏
- JZOJ4869【NOIP2016提高A组集训第9场11.7】平均数
- [JZOJ4866] 禅与园林艺术
- 【JZOJ4883】【NOIP2016提高A组集训第12场11.10】灵知的太阳信仰