链接:
https://odzkskevi.qnssl.com/76ee6a37a5e7b6e0a1da0f46372ab4da?v=1537258358
题意:
用#填充,只要有#,必须填满一行或一列。问能否分成给出的区域数。
思路:
求出连通区域的行数和列数,
(就是把联通的区域都看成一块,形成了几行几列的联通块)。假设n行m列,那么每行就有m-1个#,每列就有n-1个# ;或者说,就有n-1行#,m-1列 # 。按格式输出即可,详见代码。
#include <iostream>
#include <cstdio>
using namespace std;
int main()
{
freopen("kotlin.in","r",stdin);
freopen("kotlin.out","w",stdout);
int n,m,k;
scanf("%d%d%d",&n,&m,&k);
long long maxn=((m+1)/2)*((n+1)/2);//最多的连通区域数
if(k>maxn)
{
printf("Impossible\n");
return 0;
}
bool flag=1;
int r,c;
for(int i=1; i<=(n+1)/2; ++i) //枚举一行有多少,k必须同时被行和列上的连通数整除,且二者相乘为k
{
if(k%i==0)//
{
int tmp=k/i;
if(tmp<=(m+1)/2)
{
flag=0;
r=i; // 一列有r个连通区域
c=tmp; // 一行有c个连通区域
break;
} //其实就是把一整块联通区域看成一块,形成一个几行几列的矩阵
}
}
r--; //一列有r-1个‘#’ ,#个数总比连通区域数少一
c--; //一行有c-1个‘#’
// cout<<"R: "<<r<<endl;
// cout<<"C: "<<c<<endl;
if(flag)
{
printf("Impossible\n");
return 0;
}
int cnt1=0;
for(int i=1; i<=n; ++i)
{
int cnt2=0;
if(i%2==0&&cnt1<r)//隔一行一填#
{
cnt1++;
for(int j=1; j<=m; ++j)
printf("#");
printf("\n");
}
else
{
for(int j=1; j<=m; ++j)
{
if(j%2==0&&cnt2<c)
{
cnt2++;
printf("#");
}
else printf(".");
}
printf("\n");
}
}
return 0;
}