http://acm.hdu.edu.cn/showproblem.php?pid=1498
这道题目昨天晚上做了很久,题目意思没看懂,后来看了些网上代码,算是彻底懂了。其实是每个学生可以选择其中一种气球来踩,后面还有很多学生在排队。就是有多少种颜色的气球就有多少个学生来踩,当每种颜色的气球都被踩过K次以后,问:还有哪几种颜色的气球存在。
刚开始做了一遍,发现重复输出了好多。后来看见别人用了set容器,自己也跟着用了,提交46ms,本以为很优来了,搜下神牛的代码,发现了一个15ms的,汗。
其实人家算法和我是一样的,只不过人家用两个数组记录 等于 我的set容器。以后要少用set容器之类的系统模板,因为这样或多或少影响了我的编程能力与代码的灵敏性。。。
下面是我的代码46ms:
#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
#include<set>
using namespace std;
#define maxn 105
#define mem(str,x) memset(str,(x),sizeof(str))
int map[maxn][maxn];
bool vis[maxn];
int flag[maxn][maxn];
int per[maxn];
int ans[maxn];
int n,k;
bool find(int x)
{
for(int i=1;i<=n;i++){
if( !vis[i] && flag[x][i] ){
vis[i] = true;
if(per[i] == -1 || find( per[i] ) ){
per[i] = x;
return true;
}
}
}
return false;
}
int hungry()
{
int sum=0;
for(int i=1;i<=n;i++) per[i] = -1;
for(int i=1;i<=n;i++){
mem(vis,false);
sum+=find(i);
}
return sum;
}
int main()
{
set< int > v;
while(scanf("%d%d",&n,&k)&&n!=0&&k!=0){
mem(map,0); v.clear(); mem(ans,0);
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++){
int x;
scanf("%d",&x);
map[i][j] = x;
v.insert( map[i][j] );
}
}
if( k >= n ) printf("-1\n");
else{
int anss=0;
set<int>::iterator it;///定义前向迭代器
for(it = v.begin(); it != v.end(); it++ ){
int color = *it;
mem(flag,0);
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++){
if(map[i][j] == color)
flag[i][j] = 1;
else
flag[i][j] = 0;
}
int sum = hungry();
if(sum > k) ans[anss++] = color;
}
if(anss==0) printf("-1\n");
else{
for(int i = 0;i <anss;i++ ){
printf("%d%c",ans[i],(i==anss-1)?'\n':' ');
}
}
}
}
return 0;
}
下面是神牛代码15ms:
#include"stdio.h"
#include"string.h"
#include"stdlib.h"
int map[101][101],mark[101];
int v[101],link[101];
int a[101],color[101];
int k,n;
int cmp(const void*a,const void*b)
{
return *(int*)a-*(int*)b;
}
int dfs(int i,int k)
{
int j;
for(j=1;j<=n;j++)
{
if(map[i][j]==k&&!v[j])
{
v[j]=1;
if(link[j]==0||dfs(link[j],k))
{
link[j]=i;
return 1;
}
}
}
return 0;
}
int main()
{
int i,j,t,tt,ans;
while(scanf("%d%d",&n,&k)!=-1)
{
if(n==0&&k==0)
break;
memset(color,0,sizeof(color));
memset(mark,0,sizeof(mark));
t=0;
for(i=1;i<=n;i++)
{
for(j=1;j<=n;j++)
{
scanf("%d",&map[i][j]);
if(!mark[map[i][j]])
{
mark[map[i][j]]=1;
color[t++]=map[i][j];
}
}
}
tt=0;
for(i=0;i<t;i++)
{
ans=0;
memset(link,0,sizeof(link));
for(j=1;j<=n;j++)
{
memset(v,0,sizeof(v));
if(dfs(j,color[i]))
ans++;
}
if(ans>k)
a[tt++]=color[i];
}
if(tt==0)
printf("-1\n");
else
{
qsort(a,tt,sizeof(a[0]),cmp);
for(i=0;i<tt-1;i++)
printf("%d ",a[i]);
printf("%d\n",a[i]);
}
}
return 0;
}
其实还有好多0ms的神牛。。。。。。。