Codeforces - 441C-Valera and Tubes

来源:互联网 发布:海颐软件北京分公司 编辑:程序博客网 时间:2024/05/21 11:30

Codeforces - 441C-Valera and Tubes

原题链接:http://codeforces.com/problemset/problem/441/C

C. Valera and Tubes
time limit per test1 second
memory limit per test256 megabytes
inputstandard input
outputstandard output
Valera has got a rectangle table consisting of n rows and m columns. Valera numbered the table rows starting from one, from top to bottom and the columns – starting from one, from left to right. We will represent cell that is on the intersection of row x and column y by a pair of integers (x, y).

Valera wants to place exactly k tubes on his rectangle table. A tube is such sequence of table cells (x1, y1), (x2, y2), …, (xr, yr), that:

r ≥ 2;
for any integer i (1 ≤ i ≤ r - 1) the following equation |xi - xi + 1| + |yi - yi + 1| = 1 holds;
each table cell, which belongs to the tube, must occur exactly once in the sequence.
Valera thinks that the tubes are arranged in a fancy manner if the following conditions are fulfilled:

no pair of tubes has common cells;
each cell of the table belongs to some tube.
Help Valera to arrange k tubes on his rectangle table in a fancy manner.

Input
The first line contains three space-separated integers n, m, k (2 ≤ n, m ≤ 300; 2 ≤ 2k ≤ n·m) — the number of rows, the number of columns and the number of tubes, correspondingly.

Output
Print k lines. In the i-th line print the description of the i-th tube: first print integer ri (the number of tube cells), then print 2ri integers xi1, yi1, xi2, yi2, …, xiri, yiri (the sequence of table cells).

If there are multiple solutions, you can print any of them. It is guaranteed that at least one solution exists.

Examples
input
3 3 3
output
3 1 1 1 2 1 3
3 2 1 2 2 2 3
3 3 1 3 2 3 3
input
2 3 1
output
6 1 1 1 2 1 3 2 3 2 2 2 1
Note
Picture for the first sample:

这里写图片描述
Picture for the second sample:
这里写图片描述

题目大意:
给出 n*m 的矩阵,要求矩阵内连成 k 条水管,且水管的长度 L>=2 . 输出 k 行,每行为水管的长度 L ,及水管的坐标 x , y.

分析:
其实不必把水管刻意分成等分,可以按照最小长度做,把水管分成 k 分,1 - k-1份均为 2 ,第 k 份为 n*m-2*(k-1) .然后用连通块或者类似的方法做就可以了 .

知识小点:
‘&’– ‘与运算’
与运算即只有 1&1==1、其他情况(1&0==0、0&1==0、0&0==0).而本篇涉及了 x&1 的运算,可用于判断 x 的单双. 从逻辑角度来说,就是把 x 转换成二进制,然后与 0001 进行与运算.

AC代码实现:

#include <iostream>using namespace std;void next(int n,int m,int &x,int &y){    if (x&1) y++;    else y--;    if (y>m) x++,y--;    if (y<1) x++,y++;}void Print(int n,int m,int &x,int &y){    cout<<x<<" "<<y<<" ";    next(n,m,x,y);}int main(){    int n,m,k,x,y;    cin>>n>>m>>k;    x=y=1;    for (int i=1;i<=k;i++)    {        if (i<=k-1)        {            cout<<2<<" ";            Print(n,m,x,y);            Print(n,m,x,y);            cout<<endl;        }        else        {            cout<<n*m-2*(k-1)<<" ";            while (x<=n) Print(n,m,x,y);            cout<<endl;        }    }/*这篇代码的原作者是CF上一个大神写的,当时看到这么简略且通俗易懂的代码时我是相当激动的,以至于我连原作的ID都没有记下来,在此只能说声感谢。*/}

以下是未AC代码实现:

#include <iostream>#include <cstring>using namespace std;int vis[305][305];struct node{    int x,y;};node tmp;int k1=1;int n,m,k;void bs(int x,int y){    for (int i=-1;i<=1;i++)    {        for (int j=1;j>=-1;j--)        {            if (!vis[x+i][y+j] && i*j==0 && x+i>0&&x+i<=n&&y+j>0&&y+j<=m) {vis[x+i][y+j]=1;cout<<x+i<<" "<<y+j<<" ";bs(x+i,y+j);}        }    }}node bs2(int x,int y){    vis[x][y]=1;    node tmp2;    cout<<x<<" "<<y<<" ";    for (int i=-1;i<=1;i++)    {        for (int j=-1;j<=1;j++)        {            if (!vis[x+i][y+j] && i*j==0 && x+i>0&&x+i<=n&&y+j>0&&y+j<=m) {vis[x+i][y+j]=1;cout<<x+i<<" "<<y+j<<" ";tmp2.x=x+i;tmp2.y=y+j;return tmp2;}        }    }}int main(){    cin>>n>>m>>k;    for (int i=1;i<=n;i++)    {        for (int j=1;j<=m;j++)        {            if (k1!=k && !vis[i][j]) {k1++;cout<<2<<" ";tmp=bs2(i,j);cout<<endl;}            else tmp.x=i,tmp.y=j;        }    }    cout<<m*n-2*(k-1)<<" ";    bs(tmp.x,tmp.y);}/*这篇代码略长,简单解释一下。这篇其实思路是和上一篇差不多的,只是方法很笨。我把长度为 2 的水管的位置均标记并打印出来,并记录最后一格水管的坐标,然后根据坐标输出第 k 条水管。至于为什么没有 AC 我目前还找不到原因,若有大神找到希望可以留言或者私信我,谢谢!*/
0 0