列表

详情


NC20644. 消消乐

描述

r神在和小b比赛玩一个名为“消消乐”的游戏,在一个n*m的棋盘上,一些棋子分布在格点上,游戏玩家有一个名为超蓝光波的武器,可以消除一行或者一列的所有棋子,使用超蓝光波需要耗费一点能量,消除完所有的棋子之后,花费能量越少得分越高。
r神为了超过排名第一的小b,夺得荣誉称号“天下第一”,他需要寻求你的帮助,他希望知道最少需要使用多少次“超蓝光波”,以及在哪行、哪列使用。

输入描述

第一行两个正整数n(n<=2000),m(m<=2000);

接下来n行,每行m个字符,表示棋盘,其中“.”表示该处没有棋子,“*”表示该处有棋子,棋子个数<=100000

输出描述

第一行输出一个正整数,表示最少需要使用的“超蓝光波”次数

第二行N+1个正整数,第一个数为N,表示需要消掉的行数,从小到大输出每个需要消除的行号

第三行M+1个正整数,第一个数为M,表示需要消掉的列数,从小到大输出每个需要删除的列号

如果有多种情况,任意输出一种即可。

示例1

输入:

3 4
.*..
**.*
.*..

输出:

2
1 2
1 2

示例2

输入:

3 4
.*..
**.*
..*.

输出:

3
3 1 2 3 
0

原站题解

上次编辑到这里,代码来自缓存 点击恢复默认模板

C++14(g++5.4) 解法, 执行用时: 146ms, 内存消耗: 1120K, 提交时间: 2018-11-02 21:13:25

#include<stdio.h>
#include<string.h>
#include<vector>
using namespace std;
char str[2005];
int k, n, m, visx[2005], visy[2005], L[2005], R[2005];
vector<int> G[2005], F;
int Sech(int x)
{
	int i, v;
	visx[x] = 1;
	for(i=0;i<G[x].size();i++)
	{
		v = G[x][i];
		if(visy[v]==0)
		{
			visy[v] = 1;
			if(R[v]==-1 || Sech(R[v]))
			{
				R[v] = x, L[x] = v;
				return 1;
			}
		}
	}
	return 0;
}
int main(void)
{
	int i, j, ans;
	scanf("%d%d", &n, &m);
	for(i=1;i<=n;i++)
	{
		scanf("%s", str+1);
		for(j=1;j<=m;j++)
		{
			if(str[j]=='*')
				G[i].push_back(j);
		}
	}
	ans = 0;
	memset(L, -1, sizeof(L));
	memset(R, -1, sizeof(R));
	for(i=1;i<=n;i++)
	{
		memset(visy, 0, sizeof(visy));
		if(Sech(i))
			ans++;
	}
	memset(visx, 0, sizeof(visx));
	memset(visy, 0, sizeof(visy));
	printf("%d\n", ans);
	for(i=1;i<=n;i++)
	{
		if(L[i]==-1)
			Sech(i);
	}
	for(i=1;i<=n;i++)
	{
		if(visx[i]==0)
			F.push_back(i);
	}
	printf("%d", F.size());
	for(i=0;i<F.size();i++)
		printf(" %d", F[i]);
	puts("");
	F.clear();
	for(i=1;i<=m;i++)
	{
		if(visy[i])
			F.push_back(i);
	}
	printf("%d", F.size());
	for(i=0;i<F.size();i++)
		printf(" %d", F[i]);
	puts("");
	return 0;
}

C++11(clang++ 3.9) 解法, 执行用时: 183ms, 内存消耗: 1376K, 提交时间: 2018-11-02 19:57:16

#include<bits/stdc++.h>
#define rep(i,x,y) for (int i=(x);i<=(y);i++)
#define dprintf(...) fprintf(stderr,__VA_ARGS__)
using namespace std;
const int N=2005;
int n,m,res,cnt,head[N],vis[N],match[N],mk[N],mk2[N],r[N],c[N]; char s[N];
struct edge{int to,nxt;}e[200005];
void adde(int x,int y){e[++cnt].to=y; e[cnt].nxt=head[x]; head[x]=cnt;}
bool dfs(int u){
	for (int i=head[u],v;i;i=e[i].nxt)
		if (v=e[i].to,!vis[v]){
			vis[v]=1;
			if (!match[v]||dfs(match[v])) return match[v]=u,mk[u]=1,1;
		}
	return 0;
}
void dfs2(int u){
	for (int i=head[u],v;i;i=e[i].nxt)
		if (v=e[i].to,!mk2[v]){
			mk2[v]=1;
			dfs2(match[v]);
		}
}
int main(){
	scanf("%d%d",&n,&m);
	rep (i,1,n){
		scanf("%s",s+1);
		rep (j,1,m) if (s[j]=='*') adde(i,j);
	}
	rep (i,1,n){
		memset(vis,0,sizeof(vis));
		if (dfs(i)) res++;
	}
	printf("%d\n",res);
	rep (i,1,n) if (!mk[i]) dfs2(i);
	rep (i,1,m) if (match[i]) if (mk2[i]) c[++*c]=i; else r[++*r]=match[i];
	sort(r+1,r+1+*r); sort(c+1,c+1+*c);
	printf("%d",*r); rep (i,1,*r) printf(" %d",r[i]); puts("");
	printf("%d",*c); rep (i,1,*c) printf(" %d",c[i]); puts("");
	return 0;
}

上一题