1 条题解

  • 0
    @ 2026-3-19 0:47:30

    前言:

    感谢Wangle罔楽(给予markdown与LaTeX格式的帮助)
    rimu_awa(给予可能的错误位置警告)
    Mo_Ying(给予大力支持)(排名不分先后)
    帮助本蒟蒻完成这篇TJ

    正文:

    这道题就是要覆盖整个球面,我们以走一个序列为一次变换,每一次变换横坐标变了 xx,竖坐标变了 yy
    得到横坐标循环一次变换次数为 mgcd(x,m)\Large{\frac{m}{\gcd(x,m)}} 竖坐标循环一次变换次数为 ngcd(y,n)\Large{\frac{n}{\gcd(y,n)}} ,横竖坐标循环一次(即回到初始点)变换次数为 ${\operatorname {lcm} \left (\large{\frac{m}{\gcd(x,m)}},\large{\frac{n}{\gcd(y,n)}}\right )}$。
    即使我们构造出 gcd(x,m)=gcd(x,m)=1\gcd(x,m)=\gcd(x,m)=1,横竖坐标循环一次次数最多也只有 lcm(n,m)\operatorname{lcm(n,m)}
    因此序列长度至少为 n×m÷lcm(n,m)=gcd(n,m)n\times m \div \operatorname {lcm(n,m)}=\gcd(n,m)(下面用g来表示 gcd(n,m)\gcd(n,m))这里给出一种序列长度为g的“类矩形”构造。

    类矩形定义:如图

    这种一个矩形加右上角一个点(左下角一个点也算)被我称为“类矩形”,下同。

    证明类矩形可以覆盖全图:如下

    用这种覆盖方式,对于蓝色的那一行,长度就是 y(个数)×x(每行的长度)+1=类矩形面积y (个数) \times x (每行的长度) + 1 = 类矩形面积
    每一次变换横竖坐标的变化分别是 xx 和1(以每个类矩形的左上角为每个序列的起始点),因此只有循环完 nn 行之后才会再一次到蓝色行。
    此时横坐标变换为 n×xn\times x(模m意义下)因为 gcd(n,m)=g\gcd(n,m)=g,所以当 gcd(x,m)=1\gcd(x,m)=1 时,gcd(n×x,m)=g\gcd(n\times x,m)=g,只有变换 lcm(n,m)\operatorname{lcm(n,m)} 次后才会回到初始点。
    所以这一行被长度为 gg 的序列覆盖了 m÷gm\div g 次,共覆盖了 mm 个点,刚好为该行长度,这个结论显然也对其他行成立,因此当类矩形 gcd(x,m)=1\gcd(x,m)=1 时就可以覆盖整个球体。
    要保证序列长度为 gg ,只需要类矩形大小为 gg,也就是 x×y=g1x\times y = g-1 即可。

    这样我们就只要保证 gcd(x,m)=1\gcd(x,m)=1,可以简单的通过枚举 xx 来解决。

    接下来就是构造序列使得我们能走完类矩形并到达下一个类矩形,共有三种情况。

    一: xx 为偶数

    此时我们不一定能走遍矩形并到达右上角,但是我们只需要沿着45°斜线翻转成左下角向下多了一个点即可 行走方案如下图:

    二: yy 为偶数

    类似的,只是先向下在向右向上这样,如图:

    三: xxyy 均为奇数

    对前面两列进行特殊操作,使得在覆盖完前两列时刚好到达第二列的最后一个,在向上到第三列的第一个,就转化为情况二了,如图:
    全部情况已说明完毕,下面是代码 。 :::info[代码(本人码风较差,不建议观看)]

    #include<bits/stdc++.h>
    using namespace std;
    int gcd(int x,int y)
    {
    	if(y==0)
    	{
    		return x;
    	}
    	return gcd(y,x%y);
    }
    int main()
    {
    	int n,m;
    	cin>>n>>m;
    	int g=gcd(n,m);
    	if(g==1)//特判gcd为1的情况 
    	{
    		cout<<2<<endl;
    		cout<<"DP";
    		return 0;
    	}
    	cout<<g<<endl;
    	for(int i=1;i<=g;i++)
    	{
    		if((g-1)%i==0&&gcd((g-1)/i,m)==1)//构造类矩形 
    		{
    			int j=(g-1)/i;
    			if(i==1)
    			{
    				for(int k=1;k<=g-1;k++)
    				{
    					cout<<"P";
    				}
    				cout<<"D";
    				return 0;
    			}
    			if(j==1)
    			{
    				for(int k=1;k<=g-1;k++)
    				{
    					cout<<"D";
    				}
    				cout<<"P";
    				return 0;
    			}//矩形长度或宽度为1时特判
    			if(i%2==0)
    			{
    				for(int k=1;k<=i;k++)
    				{
    					if(k%2)
    					{
    						for(int l=1;l<=j-1;l++)
    						{
    							cout<<"P";
    						}
    					}
    					else
    					{
    						for(int l=1;l<=j-1;l++)
    						{
    							cout<<"L";
    						}
    					}
    					cout<<"D";
    				}
    				cout<<"P";
    				return 0;
    			}
    			if(j%2==0)
    			{
    				for(int k=1;k<=j;k++)
    				{
    					if(k%2)
    					{
    						for(int l=1;l<=i-1;l++)
    						{
    							cout<<"D";
    						}
    					}
    					else
    					{
    						for(int l=1;l<=i-1;l++)
    						{
    							cout<<"G";
    						}
    					}
    					cout<<"P";
    				}
    				cout<<"D";
    				return 0;
    			}
    			for(int k=1;k<=i-1;k++)
    			{
    				if(k%2)
    				cout<<"PD";
    				else
    				cout<<"LD";
    			}
    			cout<<"P";//前面的右下左下 ,完成前两列 重复 
    			for(int k=1;k<=j-2;k++)
    			{
    				cout<<"P";
    				if(k%2)
    				{
    					for(int l=1;l<=i-1;l++)
    					{
    						cout<<"G";
    					}
    				}
    				else
    				{
    					for(int l=1;l<=i-1;l++)
    					{
    						cout<<"D";
    					}
    				}
    			}//后j-2列右上(i-1个)左上(i-1个)重复 
    			cout<<"PD";//形成"类矩形"
    			return 0;
    		}
    	}
    	return 0;
    }
    

    :::

    • 1

    「POI2026 R1」太空探测车 / Łazik kosmiczny

    信息

    ID
    9640
    时间
    6000ms
    内存
    256MiB
    难度
    10
    标签
    递交数
    3
    已通过
    1
    上传者