题目:http://acm.hdu.edu.cn/showproblem.php?pid=1498
这题想了很久都没想到,看了下别人的分析,才恍然大悟,其实就是一个棋盘问题。用最少的棋子去覆盖整个棋盘。而这里是通过行列来覆盖,和车的走位一样,所以只要求每种颜色的匹配数,如果大于k就说明不能全部踩破。
方法一:
将颜色从1——max枚举。
代码:

#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中取出来求匹配数
代码:

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