codeforces815aKarenAndGames解题报告

【题目描述】


在她上学的路上,她沉迷于一款益智游戏无法自拔。

游戏是这样的:在每一关,你都有一个n行m列的网格。每个单元最初为数字0。每一步你可以选择一行或一列,并将该行或列中的所有单元格添加1。为了通关,你需要在所有的移动之后使第i行第j列的数字为g[i][j]。凯伦想知道一种使用最少步数通关的方法。


【输入格式】


第一行输入包含两个整数,分别为n和m(1≤n,m≤100),表示网格中的行数和列数。

接下来的n行每行都包含m个整数。第i行的第j个整数表示g[i][j](0≤g[i][j]≤500)。


【输出格式】


如果无法通关,输出-1。

否则,第一行输出一个整数k表示最小步数

接下来k行包含以下两项,用来描述一步操作

row x,(1<=x<=n)表示选第x行。

col x,(1<=x<=m)表示选第x列。

如果有多个答案,输出任意一个

【样例输入1】

3 5

2 2 2 3 2

0 0 0 1 0

1 1 1 2 1

【样例输出1】


4

row 1

row 1

row 3

col 4


【样例输入2】

3 3

0 0 0

0 1 0

0 0 0

【样例输出2】

-1

【样例输入3】


3 3

1 1 1

1 1 1

1 1 1


【样例输出3】


3

row 1

row 2

row 3

题解:

直接模拟。。先取行数列数中较小的一个 可以减少取的次数

代码:

#include <iostream>
#include <cstdio>
using namespace std;
int A[110][110];
int ans[110],Ans[110];
int main(){
	freopen("games.in","r",stdin);
	freopen("games.out","w",stdout);
	int n,m;
	scanf("%d %d",&n,&m);
	for(int i=1;i<=n;i++)
		for(int j=1;j<=m;j++)
			scanf("%d",&A[i][j]);
	if(n<=m){
		for(int i=1;i<=n;i++){
			int minn=0x7fffffff;
			for(int j=1;j<=m;j++)
				minn=min(minn,A[i][j]);
			for(int j=1;j<=m;j++)
				A[i][j]-=minn;
			ans[i]=minn;
		}
		for(int i=1;i<=m;i++){
			int minn=0x7fffffff;
			for(int j=1;j<=n;j++)
				minn=min(minn,A[j][i]);
			for(int j=1;j<=n;j++)
				A[j][i]-=minn;
			Ans[i]=minn;
		}
	}
	else {
		for(int i=1;i<=m;i++){
			int minn=0x7fffffff;
			for(int j=1;j<=n;j++)
				minn=min(minn,A[j][i]);
			for(int j=1;j<=n;j++)
				A[j][i]-=minn;
			Ans[i]=minn;
		}
		for(int i=1;i<=n;i++){
			int minn=0x7fffffff;
			for(int j=1;j<=m;j++)
				minn=min(minn,A[i][j]);
			for(int j=1;j<=m;j++)
				A[i][j]-=minn;
			ans[i]=minn;
		}
	}
	for(int i=1;i<=n;i++)
		for(int j=1;j<=m;j++)
			if(A[i][j]){
				puts("-1");
				return 0;
			}
	int dl=0;
	for(int i=1;i<=n;i++)
		dl+=ans[i];
	for(int i=1;i<=m;i++)
		dl+=Ans[i];
	printf("%d\n",dl);
	if(n<=m){
		for(int i=1;i<=n;i++)
			for(int j=1;j<=ans[i];j++)
				printf("row %d\n",i);
		for(int i=1;i<=m;i++)
			for(int j=1;j<=Ans[i];j++)
				printf("col %d\n",i);
	}
	else {
		for(int i=1;i<=m;i++)
			for(int j=1;j<=Ans[i];j++)
				printf("col %d\n",i);
		for(int i=1;i<=n;i++)
			for(int j=1;j<=ans[i];j++)
				printf("row %d\n",i);
	}
return 0;
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值