博弈,当N为偶数时,先手必赢,输出0,当N为奇数时,后手必赢且只有最中间的那个位置为炸弹时才能赢,输出1
不论是奇数还是偶数,炸弹在1和N这两个地方,后手必输,因为先手在炸弹在1的时候选2,在炸弹在N的时候选N - 1,则后手只能选炸弹。
对于其他情况则只需考虑2到N / 2(向上取整),因为左右的情况是对称的。
红色为炸弹,褐色为先手,绿色为后手
如果为偶数
如图,炸弹在3,先手只要选6,也就是留一个以3为对称点的区间给后手
然后若后手选1,先手要一直选1以3为对称点的那个位置,此时为5
然后一直照着选后手选的那个点关于炸弹对称点的策略,最后一定是后手先选到炸弹
也就是说要给后手一直留一个如图[1, 5]的对称区间的陷阱,这个陷阱的长度易知一定为奇数,因为是对称的,炸弹换到其他地方同理可得
当N为偶数的时候后手在第一步的时候总能给后手构造这么个区间,也就是以N为偶数的时候后手必输
所以合适的炸弹位置为0
同样的,N为奇数时也只需要考虑半个区间就行了,如炸弹在3这种情况,采取和上面一样的策略,先手选6,给后手留[1, 5]对称区间,则由上面知道后手必输,
炸弹在2的时候也一样
只有当炸弹在4的时候
先手第一步让自己入陷阱了,而且没有别的选择,这时后手只要反客为主选与7以4位对称点的那个位置,一直这种策略选下去,则后手必赢
发现只有炸弹在4这个对称中心的时候后手才能赢,因此N为奇数的时候输出1
综上:N为偶数的时候输出0,N为奇数的时候输出1
#include <cstdio> #include <iostream> #include <algorithm> #include <cstring> #include <cstdlib> using namespace std; int main() { int T, n; cin >> T; while (T--) { scanf("%d", &n); if (n % 2 != 0) { printf("1\n"); } else { printf("0\n"); } } return 0; }