1 条题解

  • 0
    @ 2025-8-24 21:36:47

    自动搬运

    查看原文

    来自洛谷,原作者为

    avatar Zhou_yu
    这个家伙很懒,但什么都想留下||CZOIer

    搬运于2025-08-24 21:36:47,当前版本为作者最后更新于2023-08-29 10:05:18,作者可能在搬运后再次修改,您可在原文处查看最新版

    自动搬运只会搬运当前题目点赞数最高的题解,您可前往洛谷题解查看更多

    以下是正文


    题目描述:

    P2361题目传送门

    算法思路:

    一道必胜策略好题。

    应对方法:

    须知:以下式子中 AA 为长, BB 为宽。

    1. 如果有中心点,己方先手,下中心点。

    (通俗讲,如果长宽都是奇数,自己先手下 (A/2+1,B/2+1)(A/2+1,B/2+1) 位置)

    1. 下对手中心对称的位置,举个例子,如果对手下 (x,y)(x,y),我们就下在 (Ax+1,By+1)(A-x+1,B-y+1)

    (通俗讲,粘着对手下!

    位置问题解决了,但是颜色该怎么办呢?

    1. 考虑长宽都是奇数:

    奇数不会出现 (x,y)(x,y)(Ax+1,By+1)(A-x+1,B-y+1) 旁边,所以下的颜色跟对手一样。

    2. 考虑长或宽有偶数:

    偶数会出现 (x,y)(x,y)(Ax+1,By+1)(A-x+1,B-y+1) 旁边,所以反着对手的颜色下。

    (举个例子,A=3,B=2,x=2,y=1A=3,B=2,x=2,y=1,要下的是:(2,2)(2,2),在对手下面)

    蒟蒻のAC代码

    AC记录

    #include <bits/stdc++.h>
    using namespace std;
    int a,b;
    struct node
    {
    	bool is_full=0;//有没有被下过
    	int color=-1;//什么颜色
    	bool can_be_1=1;//可以下黑棋
    	bool can_be_0=1;//可以下白棋
    }f[10][10];
    int dx[4]={0,0,1,-1};
    int dy[4]={1,-1,0,0};
    void out()
    {
    	cout<<"Buwanle";
    	exit(0);
    }
    int main()
    {
    	ios::sync_with_stdio(0);
    	cin.tie(0);cout.tie(0);
    	cin>>a>>b;
    	int t=0,flag=1;
    	if(a%2)t++;
    	if(b%2)t++;
       //t作用是看长宽是否都是奇数
    	if(t==2)cout<<"First";
    	else
    	{
    		cout<<"Second";
    		flag=0;
    	}
    	cout<<'\n';
    	if(t==2)
    	{
        //都是奇数的话先手,下中心点
    		cout<<a/2+1<<' '<<b/2+1<<' '<<1<<'\n';
    		for(int i=0;i<4;i++)
    		{
    			int tx=dx[i]+a/2+1;
    			int ty=dy[i]+b/2+1;
    			if(tx<1||ty<1||tx>a||ty>b)continue;
    			f[tx][ty].can_be_1=0;
    		}
    	}
    	int x,y,c;
    	while(cin>>x>>y>>c)
    	{
    		
    		if(f[x][y].is_full)out();//已被下过
    		if(c==1&&f[x][y].can_be_1==0)out();//不可以下黑棋却下黑棋
    		if(c==0&&f[x][y].can_be_0==0)out();//不可以下白棋却下白棋
    		f[x][y].is_full=1;
    		f[x][y].color=c;
    		for(int i=0;i<4;i++)
    		{
    			int tx=dx[i]+x;
    			int ty=dy[i]+y;
    			if(tx<1||ty<1||tx>a||ty>b)continue;
    			if(c==1)f[tx][ty].can_be_1=0;
    			else f[tx][ty].can_be_0=0;
    		}//给上下左右附上不可以下同样颜色
    		int will_color=c;
    		if(!flag)
    		{
    			if(c==1)will_color=0;
    			else will_color=1;
    		}//看需要下什么颜色
    		int will_choose_x=a-x+1;
    		int will_choose_y=b-y+1;
       		//中心对称
    		cout<<will_choose_x<<' '<<will_choose_y<<' '<<will_color<<'\n';
         		//粘着对手下
    		for(int i=0;i<4;i++)
    		{
    			int tx=dx[i]+will_choose_x;
    			int ty=dy[i]+will_choose_y;
    			if(tx<1||ty<1||tx>a||ty>b)continue;
    			if(will_color==1)f[tx][ty].can_be_1=0;
    			else f[tx][ty].can_be_0=0;
    		}//给上下左右附上不可以下同样颜色
    	}
    	return 0;
    }
    

    总结:

    遇事不决,小学数学!

    • 1

    信息

    ID
    1646
    时间
    1000ms
    内存
    125MiB
    难度
    4
    标签
    递交数
    0
    已通过
    0
    上传者