codeforces 394C Dominoes

题目链接

题意:

给出n*m张牌,每张牌上有两个数字,有0和1组成,这两个数字可以互换,重新排列牌的顺序,算出每一列的和,使得这些和的最大值达到最小


解题思路:

分别计算出11,10,01,00的个数,将10,01的个数相加,这两个数实质上是一样的,因为数字可以互换,从大到小将这几个数放在一个n*m的数组中,其中在放10和01时,一行放10,一行放01

蛇行输出即可


#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <string>
using namespace std;
int str[1005][1005],s[1005][1005];
int sum[2500];
int num[20];
int main()
{
	int n,m;
	int all=0;
	scanf("%d%d",&n,&m);
	memset(num,0,sizeof(num));
	int t=0;
	for(int i=1;i<=n;i++)
	{
		for(int j=1;j<=m;j++)
		{
			scanf("%d",&str[i][j]);
			if(str[i][j]==10 || str[i][j]==1) all++;
			if(str[i][j]==0) all+=2;
			num[str[i][j]]++;
		}
	} 
	t=1;
	int l=2;
	memset(sum,0,sizeof(sum));
	for(int i=1;i<=m;i++)
	{
		for(int j=1;j<=n;j++)
		{
			sum[t]+=str[j][i]/10;
			sum[l]+=str[j][i]%10;
		}
		t+=2;l+=2;
	}
	int maxn = -50000,minx = 50000;
	for(int i=1;i<=2*m;i++)
	{
		maxn=max(maxn,sum[i]);
		minx=min(minx,sum[i]);
	}
	if(maxn==minx || all/(2*m)==maxn)//判断是否已经达到要求,如果是就直接输出,不用换顺序 
	{
		for(int i=1;i<=n;i++)
		{
			for(int j=1;j<=m;j++)
			{
				if(j==m) printf("%02d\n",str[i][j]);
				else printf("%02d ",str[i][j]);
			}
		}
		return 0;
	}
	int flag1=1,flag2=1;
	int t1=0,t2=0;
	num[1]+=num[10];
	int p=1;
	for(int i=1;i<=n;i++)
	{
		for(int j=1;j<=m;j++)
		{
			if(num[11]==0) flag1=0;
			if(num[11]!=0) 
			{
				s[i][j]=11;
				num[11]--;
				if(num[11]==0) 
				{
					t1=j;
				}
				continue;
			}
			if(num[1]==0) flag2=0;
			if(flag1==0 && flag2==1) 
			{
				if(p==1)
				{
					s[i][j]=10;
				}
				else
				{
					s[i][j]=1;
				}
				num[1]--;
				continue;
			}
			if(num[1]==0) flag2=0;
			if(flag1==0 && flag2==0)
			{
				s[i][j]=0;
				num[0]--;
			}
		}
		p = -p;
	}
	for(int i=1;i<=n;i++)
	{
		if(i%2==1)
		for(int j=1;j<=m;j++)
		{
			if(j==m) printf("%02d\n",s[i][j]);
			else printf("%02d ",s[i][j]);
		}
		else
			for(int j=m;j>=1;j--)
			{
				if(j==1) printf("%02d\n",s[i][j]);
				else printf("%02d ",s[i][j]);
			}
	}
	return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值