构造问题(special judge) (持续更新)

构造问题的核心就是推出通式解决问题,找到一个手填的一般方案,这才能编程表达出来。。

在数据规模较小的时候优先考虑递归 

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;
}

猜你喜欢

转载自blog.csdn.net/neuq_zsmj/article/details/82284626
今日推荐