【问题描述】
? × ?的方阵上有?棵葱,你要修一些栅栏把它们围起来。一个栅栏是一段
沿着网格建造的封闭图形(即要围成一圈) 。各个栅栏之间应该不相交、不重叠
且互相不包含。如果你最多修?个栅栏,那么所有栅栏的长度之和最小是多少?
【输入格式】
第一行三个整数?, ?, ?。
接下来?行每行两个整数?, ?代表某棵葱的位置。
【输出格式】
一行一个整数代表答案。
【样例输入 1】
6 1 4
1 3
4 2
4 4
6 4
【样例输出 1】
18
【样例输入 2】
6 2 4
1 3
4 2
4 4
6 4
【样例输出 2】
16
第 5 页 共 5 页
【数据规模与约定】
对于10%的数据,? = 1。
对于30%的数据,? ≤ 2。
对于60%的数据,? ≤ 10。
对于100%的数据,1 ≤ ? ≤ ? ≤ 16, ? ≤ 1000。
#include <iostream>
#include <cstdio>
using namespace std;
int m,k,n;
int x1=1000000,x2=-1,y1=1000000,y2=-1,x,y;
void work()
{
for(int i=1;i<=n;i++)
{
scanf("%d%d",&x,&y);
x1=min(x1,x);y1=min(y1,y);
x2=max(x2,x);y2=max(y2,y);
}
long long ans=(y2-y1+1+x2-x1+1)*2;
printf("%lld",ans);
return ;
}
int ans=1e9+7;
struct node
{
int x,y;
}a[1000];
int c[100][100];
void dfs(int x)
{
if(x>n)
{
int sum=0;
for(int i=1;i<=k;i++)
{
int minx=1e9+7,miny=1e9+7,maxx=-2,maxy=-2;
for(int j=1;j<=c[i][0];j++)
{
int t=c[i][j];
// cout<<i<<" "<<t<<endl;
minx=min(minx,a[t].x);
miny=min(miny,a[t].y);
maxx=max(maxx,a[t].x);
maxy=max(maxy,a[t].y);
}
if(c[i][0]>0)
sum+=(maxx-minx+1+maxy-miny+1)*2;
}
//cout<<sum<<"ssss"<<endl;
//cout<<"----------------------"<<endl;
ans=min(sum,ans);
return ;
}
for(int i=1;i<=min(x,k);i++)
{
c[i][0]++;
c[i][c[i][0]]=x;
dfs(x+1);
c[i][0]--;
}
}
int main()
{
freopen("dan.in","r",stdin);
freopen("dan.out","w",stdout);
scanf("%d%d%d",&m,&k,&n);
if(k==1)
{
work();
}
else
{
for(int i=1;i<=n;i++)
scanf("%d%d",&a[i].x,&a[i].y);
dfs(1);
printf("%d",ans);
}
fclose(stdin);
fclose(stdout);
return 0;
}