HDU 1498 50 years, 50 colors

题目:http://acm.hdu.edu.cn/showproblem.php?pid=1498

这题想了很久都没想到,看了下别人的分析,才恍然大悟,其实就是一个棋盘问题。用最少的棋子去覆盖整个棋盘。而这里是通过行列来覆盖,和车的走位一样,所以只要求每种颜色的匹配数,如果大于k就说明不能全部踩破。

方法一:

将颜色从1——max枚举。

代码:

View Code
#include<stdio.h>
#include
<string.h>

int n,color[101][101],mark[101],ans[51];
bool map[101][101],visit[101];

void get_map(int key)
{
int i,j;
for(i=0;i<n;i++)
{
for(j=0;j<n;j++)
{
if(color[i][j]==key)
map[i][j]
=1;
else
map[i][j]
=0;
}
}
}

bool dfs(int k)
{
int i;
for(i=0;i<n;i++)
{
if(map[k][i]&&!visit[i])
{
visit[i]
=1;
if(!mark[i]||dfs(mark[i]))
{
mark[i]
=k;
return true;
}
}
}
return false;
}

int solve()
{
int i,num=0;
memset(mark,
0,sizeof(mark));
for(i=0;i<n;i++)
{
memset(visit,
0,sizeof(visit));
if(dfs(i))
num
++;
}
return num;
}

int main()
{
int i,j,k,max;
while(scanf("%d%d",&n,&k)!=EOF)
{
max
=0;
for(i=0;i<n;i++)
{
for(j=0;j<n;j++)
{
scanf(
"%d",&color[i][j]);
if(max<color[i][j])
max
=color[i][j];
}
}
j
=0;
for(i=1;i<=max;i++)
{
get_map(i);
if(solve()>k)
ans[j
++]=i;
}
if(j==0)
{
printf(
"-1\n");
continue;
}
for(i=0;i<j;i++)
{
if(i==0)
printf(
"%d",ans[i]);
else
printf(
" %d",ans[i]);
}
printf(
"\n");
}
return 0;
}

方法二:

用set接收输入的颜色,再从set中取出来求匹配数

代码:

View Code
#include<stdio.h>
#include
<string.h>
#include
<set>
using namespace std;
int n,color[110][110],mark[110],ans[51];
bool map[110][110],visit[110];
set<int>col;
set<int>::iterator it;
void get_map(int key)
{
int i,j;
for(i=0;i<n;i++)
{
for(j=0;j<n;j++)
{
if(color[i][j]==key)
map[i][j]
=1;
else
map[i][j]
=0;
}
}
}

bool dfs(int k)
{
int i;
for(i=0;i<n;i++)
{
if(map[k][i]&&!visit[i])
{
visit[i]
=1;
if(mark[i]==-1||dfs(mark[i]))
{
mark[i]
=k;
return true;
}
}
}
return false;
}

int solve()
{
int i,num=0;
memset(mark,
-1,sizeof(mark));
for(i=0;i<n;i++)
{
memset(visit,
0,sizeof(visit));
if(dfs(i))
num
++;
}
return num;
}

int main()
{
int i,j,k,max;
while(scanf("%d%d",&n,&k)!=EOF&&n+k!=0)
{
col.clear();
max
=0;
for(i=0;i<n;i++)
{
for(j=0;j<n;j++)
{
scanf(
"%d",&color[i][j]);
col.insert(color[i][j]);
}
}
j
=0;
for(it=col.begin();it!=col.end();it++)
{
get_map(
*it);
if(solve()>k)
ans[j
++]=*it;
}
if(j==0)
{
printf(
"-1\n");
continue;
}
for(i=0;i<j;i++)
{
if(i==0)
printf(
"%d",ans[i]);
else
printf(
" %d",ans[i]);
}
printf(
"\n");
}
return 0;
}

  

原文地址:https://www.cnblogs.com/lujiacheng/p/2115867.html