[GCJ14 R1A Problem A]Charging Chaos 位运算+矩阵

2014年Google Code Jam Round 1A ProblemA 

好久没打GCJ了,有点生疏啊...读题都要花很长时间...

题目是这样的~


Problem

Shota the farmer has a problem. He has just moved into his newly built farmhouse, but it turns out that the outlets haven't been configured correctly for all of his devices. Being a modern farmer, Shota owns a large number of smartphones and laptops, and even owns a tablet for his favorite cow Wagyu to use. In total, he owns N different devices.

As these devices have different specifications and are made by a variety of companies, they each require a different electric flow to charge. Similarly, each outlet in the house outputs a specific electric flow. An electric flow can be represented by a string of 0s and 1s of length L.

Shota would like to be able to charge all N of his devices at the same time. Coincidentally, there are exactlyN outlets in his new house. In order to configure the electric flow from the outlets, there is a master control panel withL switches. The ith switch flips the ith bit of the electric flow from each outlet in the house. For example, if the electric flow from the outlets is:

Outlet 0: 10
Outlet 1: 01
Outlet 2: 11

Then flipping the second switch will reconfigure the electric flow to:

Outlet 0: 11
Outlet 1: 00
Outlet 2: 10

If Shota has a smartphone that needs flow "11" to charge, a tablet that needs flow "10" to charge, and a laptop that needs flow "00" to charge, then flipping the second switch will make him very happy!

Misaki has been hired by Shota to help him solve this problem. She has measured the electric flows from the outlets in the house, and noticed that they are all different. Decide if it is possible for Shota to charge all of his devices at the same time, and if it is possible, figure out the minimum number of switches that needs to be flipped, because the switches are big and heavy and Misaki doesn't want to flip more than what she needs to.

Input

The first line of the input gives the number of test cases, T.T test cases follow. Each test case consists of three lines. The first line contains two space-separated integersN andL. The second line contains N space-separated strings of lengthL, representing the initial electric flow from the outlets. The third line also containsN space-separated strings of lengthL, representing the electric flow required by Shota's devices.

Output

For each test case, output one line containing "Case #x: y", where x is the case number (starting from 1) and y is the minimum number of switches to be flipped in order for Shota to charge all his devices. If it is impossible,y should be the string "NOT POSSIBLE" (without the quotes). Please note that our judge is not case-sensitive, but it is strict in other ways: so although "not  possible" will be judged correct, any misspelling will be judged wrong. We suggest copying/pasting the string NOT POSSIBLE into your code.

Limits

1 ≤ T ≤ 100.
No two outlets will be producing the same electric flow, initially.
No two devices will require the same electric flow.

Small dataset

1 ≤ N ≤ 10.
2 ≤ L ≤ 10.

Large dataset

1 ≤ N ≤ 150.
10 ≤ L ≤ 40.

Sample


Input
 

Output
 
3
3 2
01 11 10
11 00 10
2 3
101 111
010 001
2 2
01 10
10 01

Case #1: 1
Case #2: NOT POSSIBLE
Case #3: 0

Explanation

In the first example case, Misaki can flip the second switch once. The electric flow from the outlets becomes:

Outlet 0: 00
Outlet 1: 10
Outlet 2: 11

Then Shota can use the outlet 0 to charge device 1, the outlet 1 to charge device 2, outlet 2 to charge device 0. This is also a solution that requires the minimum amount number of switches to be flipped.

基本的题意就是给定N种电器所需要的电流样式(互不相同),以及现有的电流样式(互不相同)。每次我们可以改变所有样式的第i个电流(0变1,1变0). 求出为了使得所有的电器全部匹配拥有的电流样式,所要改变的次数最小值。


小数据的思路就是n!的复杂读直接枚举,本来也想这样做,但是发现自己写n!的水平太差了...

于是想到每一种调整方案我们都用位运算的方式进行处理.

如n=3 对第一个和第三个位置调整 就可记为(101) 即十进制下的5.

而对于每一种电流,它对应到每一个电器上都需要作出一定的改变,我们用c[i][j]来记录第i个电流样式为了符合第j个电器所做的改变的方案。

矩阵作出后对于每一种改变方案,若有c[x1][y1]==c[x2][y2]则在该改变作出的同时,电流x1和电器y1,电流x2和电器y2都可以进行匹配。最终题目要求的是所有的电流与电器都得到匹配。即是否


其中p1,p2…pn为1,2...n的一种排列方案。

则直接枚举第一列的方案k,并观察这种方案:1.能否匹配(是否在每一行每一列都能找到) 2.是否操作数最少。


code(交了四次才过,基本功还是要熟练):

#include <iostream>
#include <cstring>
#include <cstdio>
using namespace std;
char a[205][45],b[205][45],o;
long long c[250][150],base[45],rr[155],cc[155];//rr与cc分别代表当前行和当前列是否存在可行方案 
int i,p,j,k,l,n,m,t,cl,ro,tem;
long long ans;
long long cmp(long long x,long long y) //判断当前可行方案是否操作数最少
{
	long long xx,yy,tx,ty;
	if (x==-1) return y;
	xx=yy=0;
	tx=x;ty=y;
	while (tx)
	{
		if (tx%2) ++xx;
		tx/=2;
	}
	while (ty)
	{
		if (ty%2) ++yy;
		ty/=2;
	}
	if (xx>yy) return y;
	else return x;
}
main()
{
	freopen("1.in","r",stdin);
	freopen("1.out","w",stdout);//文件绑定部分 
	l=0;
	base[1]=1;
	for (i=2;i<=40;i++)
		base[i]=2*base[i-1];//位运算的基数 
	scanf("%d",&t);
	while(t--)
	{
		ans=-1;
		memset(c,0,sizeof(c)); 
		scanf("%d%d",&n,&m);
	
		scanf("%c",&o);
		for (i=1;i<=n;i++)
			{
				for	(j=1;j<=m;j++)
					scanf("%c",&a[i][j]);
				scanf("%c",&o);
			}
		for (i=1;i<=n;i++)
			{
				for	(j=1;j<=m;j++)
					scanf("%c",&b[i][j]);
				scanf("%c",&o);
			}
	for (i=1;i<=n;i++)
		for (j=1;j<=n;j++)
		 {
			for (k=1;k<=m;k++)
			if (a[i][k]!=b[j][k]) c[i][j]+=base[m-k+1];//构造c[i][j]矩阵 
		}
	for (k=1;k<=n;k++)
		{
		cl=ro=0;
		memset(rr,0,sizeof(rr));
		memset(cc,0,sizeof(cc));
		for (i=1;i<=n;i++)
			for (j=1;j<=n;j++)
			if (c[i][j]==c[k][1]) {rr[i]=1;cc[j]=1;}
		for (i=1;i<=n;i++)
			cl+=rr[i];
		for (i=1;i<=n;i++)
			ro+=cc[i];
		if (ro==n&&cl==n) 
			ans=cmp(ans,c[k][1]);
		}


	printf("Case #%d: ",++p);
	if (ans==-1)
	printf("NOT POSSIBLE\n");
	else {
		tem=0;
		while (ans)
		{
			if (ans%2) ++tem;
			ans/=2;
		}
	printf("%d\n",tem);	
	}
	}
	return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值