题目链接:http://codeforces.com/problemset/problem/43/D
题意:给出n和m,表示广场是n行m列,起点为(1,1),(可以走“上下左右”四个方向)或者建造传送门从一个点直接跳到另一个点。问从起点走完全部的格子再回到起点最少需要建造几个传送门。
要求输出传送门个数,然后传送门的起点终点,然后走的路径。
分析:分类讨论。因为题目说明面积>=2,所以不用考虑n,m是1,1的情况,然后特判n,m全都<=2的情况。需要0个传送门。其他(n=1||m=1)和(n是奇数&&m是奇数)的情况需要一个传送门,其他需要0个。详细看代码。
代码:
#include<bits/stdc++.h>
using namespace std;
int main()
{
int n,m;
scanf("%d%d",&n,&m);
if(n==1||m==1||(n%2&&m%2))
{
if((n==1&&m==2)||(n==2&&m==1))
{
puts("0");
printf("1 1\n");
printf("%d %d\n",n,m);
printf("1 1\n");
return 0;
}
puts("1");
printf("%d %d 1 1\n",n,m);
if(n==1)
{
for(int i=1; i<=m; i++)
{
printf("%d %d\n",n,i);
}
}
else if(m==1)
{
for(int i=1; i<=n; i++)
{
printf("%d %d\n",i,m);
}
}
else
{
int ff=1;
for(int i=1; i<=n; i++)
{
for(int j=1; j<=m; j++)
{
if(i%2)
printf("%d %d\n",i,j);
else
printf("%d %d\n",i,m-j+1);
}
ff^=1;
}
}
puts("1 1");
}
else
{
puts("0");
if(m%2==0)
{
for(int i=1;i<=m;i++)
{
printf("%d %d\n",1,i);
}
for(int j=m;j>=1;j--)
for(int i=2;i<=n;i++)
{
if(j%2==m%2)
printf("%d %d\n",i,j);
else
printf("%d %d\n",n-i+2,j);
}
puts("1 1");
}
else if(n%2==0)
{
for(int i=1;i<=n;i++)
{
printf("%d %d\n",i,1);
}
for(int j=n;j>=1;j--)
for(int i=2;i<=m;i++)
{
if(j%2==n%2)
printf("%d %d\n",j,i);
else
printf("%d %d\n",j,m-i+2);
}
puts("1 1");
}
}
}