2018.01.20【GDKOI2018】模拟B组

T1:直接模拟,然后排序即可。但是要注意精度问题:C++是五舍六入得,所以最后输出时要加0.001。


T2:我们可以采用贪心的思想:如果x加y可以合成a且x的钱加y的钱小于a的钱,那么我们便可以将a的钱改成x加y的钱。而如果一个a被更新了,那么我们又可以用它来更新其他值。

于是我们就想到了用dfs。首先循环所有点,以每一个点为起点做一遍dfs。dfs时如果能更新则继续dfs,否则就不dfs。最终答案就是c[1]。

从不可以被合成的点开始可以提高效率。


T3:首先,以为黑白之间的连边数是相同的,所以n*b=m*c,即n/m=c/b。

再者,(n*a)/2与(m*d)/2必须是整数。最后n>a,n>=c,m>=b,m>d。

结合以上几个条件,我们便可以求出n和m。我们让n、m从0开始,每次n加上c/gcd(c,b),m加上b/gcd(c,b),然后判断是否符合条件。这样的n、m就一定是最小的。

求出了n、m之后,我们考虑怎样连边。首先来看看怎样练黑白边。对于1号白点,它可以连1~b号黑点,2号白点又可以连b+1~2*b号黑点……以此类推。直到循环玩m个黑点之后又回到1号黑点,这样一定可以得到合法方案。

连同色点也是一样的。只不过我们需要判断一下是否之前已经连过和是否已经连够点。


T4:这题很难理解,但是特别巧妙。


首先,我们一定要把空格移到目标棋子旁边。而移了之后该怎么做呢?仔细想一下,发现我们可以有两种做法。一就是把空格和棋子交换,二就是移动空格。而移动空格一定要把空格移到棋子另一个方向的相邻的格子才有意义(因为这样棋子才能继续移动)。所以此时我们点有了思路。

设f[i][j][k]表示棋子在(i,j)位置,空格在它的k方向的相邻的格子上的最小步数。那么若要移动棋子到空格,方向就会刚好相反,坐标也会变化,步数要加1。若要把空格移动到棋子的另一个方向的相邻的格子上,那么棋子的坐标不变,方向改变,关键是步数要加几。这时我们可以发现对于同一位置从一个方向移到另一个方向的步数是一定的。所以我们设g[i][j][k][l]表示棋子在(i,j)位置,空格从它的k方向的临格移动到l方向的临格所需的步数,这个可以用bfs预处理出来。接下来,每一次我们都用bfs来求出空格从初始位置移到棋子的初始位置的4个临格的最小步数,也就是给f[sx][sy][1~4]赋初始值。最后,我们用SPFA求出f的其他值,答案就是min(f[tx][ty][1~4])。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值