构造问题的核心就是推出通式解决问题,找到一个手填的一般方案,这才能编程表达出来。。
在数据规模较小的时候优先考虑递归
2015 icpc 北京站 I 题 snake carpet
题目大意:有n条蛇,第i条蛇长度为i,要求第奇数个蛇有奇数个转折点(除了1)第偶数个蛇有偶数个转折点(除了2)
密铺矩形,输出矩形的长宽 并顺序输出蛇的坐标
思路:
先固定矩形,根据等差数列公式:偶数:n+1 , n/2 奇数: n , (n+1)/2
例如:7->(4,7) 8->(4,9)
考虑n比较小,可以用递推来写。
n为偶数时:注意到从奇数n-1到偶数n的矩形变化是长边+2,而此时的短边正好是n/2,正好可以添加一个转折点为2的蛇
n为奇数时:比较复杂。。我没有发现往前推两个到上一个奇数的合法填法,所以我再往前推了一个推到 (n-3)这个偶数
按照如图的方式填蛇可以满足递推规律,先打前三个的表,然后递推完事
#include <iostream>
using namespace std;
void solve(int n)
{
if(n==1)
{
cout<<"1 1"<<endl;
}
else if(n==2)
{
cout<<"1 1"<<endl;
cout<<"1 2 1 3"<<endl;
}
else if(n==3)
{
cout<<"1 2"<<endl;
cout<<"1 3 2 3"<<endl;
cout<<"1 1 2 1 2 2"<<endl;
}
else if(n%2==1)
{
solve(n-3);//n-3为偶数 长宽为 (n-3)/2 , n-2
//n-2(odd)
int tempy=n-1;
int time=n-2;
for(int i=1;i<=(n-3)/2;i++)//y不变
{
time--;
cout<<i<<' '<<tempy<<' ';
}
int tempx=(n-1)/2;
for(int i=n-1;time>0;i--)//x不变
{
time--;
cout<<tempx<<' '<<i<<' ';
}
cout<<endl;
//n-1(even)
for(int i=1;i<=(n-1)/2;i++)
{
cout<<tempx<<' '<<i<<' ';
}
tempx++;
for(int i=(n-1)/2;i>=1;i--)
{
cout<<tempx<<' '<<i<<' ';
}
cout<<endl;
//n(odd)
tempy=n;
time=n;
for(int i=1;i<(n+1)/2;i++)
{
time--;
cout<<i<<' '<<tempy<<' ';
}
tempx=(n+1)/2;
for(int i=n;time>0;i--)
{
time--;
cout<<tempx<<' '<<i<<' ';
}
cout<<endl;
}
else if(n%2==0)//当前的数为n 长宽为 n+1,n/2
{
solve(n-1);
int temp=n;
for(int i=1;i<=n/2;i++)
{
cout<<i<<' '<<temp<<' ';
}
temp++;
for(int i=n/2;i>=1;i--)
{
cout<<i<<' '<<temp<<' ';
}
cout<<endl;
}
return;
}
int main()
{
ios::sync_with_stdio(false);
int n;
while(cin>>n)//S=(n+1)n/2;
{
if (n % 2)
{
cout << (n+1)/2<<' '<< n << endl;
}
else if (n % 2 == 0)
{
cout <<n/2<<' ' <<n+1 << endl;
}
solve(n);
}
return 0;
}