计蒜客 31 工作区的颜值选择(简单)

题目链接:http://nanti.jisuanke.com/t/431

题面:

360硅谷范的工作区被划为了 n 行 m 列的连续工位,每个工位上可以安排一名员工工作。当第 i 行第 j 列(行和列都从1开始编号)的工位中坐着一个颜值为 C 的员工时,公司会需要付出的成本是 (|C + i + j| ⊕ U) * W(其中⊕是按位异或符号)。U 是这个工位的风水指数,W 是这个工位上接收到360安全路由发出的wifi信号强度。

比较有意思的是,两个相邻的工位(同行相邻列或同列相邻行)上坐着颜值为 C1 和 C2 的员工时,公司会额外付出 |C1 + C2| 的成本。

找到一种方案,决定每个工位上的员工应有的颜值 C (|C| ≤ k),使得公司最终需要付出的总成本最小。并输出需要付出的最小总成本。

输入格式

第一行输入三个整数 n, m, k (1 ≤ k ≤ 30) 分别表示工区的长、宽、和颜值绝对值的上限。

接下来读入两个 n 行 m 列的整数矩阵。

第一个矩阵表示每个工位的风水指数 Ui,j (1 ≤ Ui,j ≤ 30)。

第二个矩阵表示每个工位收到360安全路由发出的wifi信号强度Wi,j (1 ≤ Wi,j ≤ 30 且 Wi,j 为整数)。

对于简单版本,1 ≤ n ≤ 2,1 ≤ m ≤ 3;

对于中等版本,n = 2, 1 ≤ m ≤ 30;

对于困难版本,1 ≤ n, m ≤ 30。

输出格式

输出一个数,表示公司需要付出的最小成本。

样例1

输入:

2 2 2
1 0
1 0
1 1
1 1

输出:

11
提示信息

样例的填充方案如下:

-1 1

0 -1


题意:求本身代价和附加代价的累加值最小。


解法:

     没什么特别的思路,因为简单模式数据量很小,但直接暴力又会超时,加一个当当前值大于已有答案值的时候跳出,即可解题。


代码:

#include <algorithm>
#include <string>
#include <iomanip>
#include <iostream>
#include <cstdio>
#define LL long long
#define eps 1e-7
#define pi acos(-1)
using namespace std;
int wifi[32][32];
int u[32][32],temp;
int main()
{
	int n,m,xx,ans=99999999,tmp,a,b,c,d,e;
    scanf("%d%d%d",&n,&m,&xx);
    for(int i=1;i<=n;i++)
	{
		for(int j=1;j<=m;j++)
		{
			scanf("%d",&u[i][j]);
		}
	}
	for(int i=1;i<=n;i++)
	{
		for(int j=1;j<=m;j++)
		{
			scanf("%d",&wifi[i][j]);
		}
	}
	int amount=n*m;
	//printf("%d",amount);
	if(amount==1)
	{
		for(int i=-xx;i<=xx;i++)
		{
			tmp=(abs(i+2)^u[1][1])*wifi[1][1];
			if(tmp<ans)ans=tmp;
		}
		printf("%d\n",ans);
	}
	else if(amount==2)
	{
		if(n==1)
		{
			for(int i=-xx;i<=xx;i++)
			{
				for(int j=-xx;j<=xx;j++)
				{
					tmp=(abs(i+2)^u[1][1])*wifi[1][1]+(abs(j+3)^u[1][2])*wifi[1][2]+abs(i+j);
					if(tmp<ans)ans=tmp;
				}
			}
		}
		else 
		{
            for(int i=-xx;i<=xx;i++)
			{
				for(int j=-xx;j<=xx;j++)
				{
					tmp=(abs(i+2)^u[1][1])*wifi[1][1]+(abs(j+3)^u[2][1])*wifi[2][1]+abs(i+j);
					if(tmp<ans)ans=tmp;
				}
			}

		}
		printf("%d\n",ans);
	}
	else if(amount==3)
	{
		for(int i=-xx;i<=xx;i++)
			{
				for(int j=-xx;j<=xx;j++)
				{
					for(int k=-xx;k<=xx;k++)
				   {	tmp=(abs(i+2)^u[1][1])*wifi[1][1]+(abs(j+3)^u[1][2])*wifi[1][2]+(abs(k+4)^u[1][3])*wifi[1][3]+abs(i+j)+abs(j+k);
					if(tmp<ans)ans=tmp;}
				}
			}
         printf("%d\n",ans);
	}
	else if(amount==4)
	{
			for(int i=-xx;i<=xx;i++)
			{
				for(int j=-xx;j<=xx;j++)
				{
					for(int k=-xx;k<=xx;k++)
                    {
						for(int z=-xx;z<=xx;z++)
						{
					     tmp=(abs(i+2)^u[1][1])*wifi[1][1]+(abs(j+3)^u[1][2])*wifi[1][2]+(abs(k+3)^u[2][1])*wifi[2][1]+(abs(z+4)^u[2][2])*wifi[2][2]+abs(i+j)+abs(i+k)+abs(k+z)+abs(j+z);
					     if(tmp<ans)ans=tmp;
						}
					}
				}
			}
			printf("%d\n",ans);
	}
	else if(amount==6)
	{
		bool flag=false;
		int l1,l2,l3,l4,l5,l6;
		l1=xx;
		l2=xx;
		l3=xx;
		l4=xx;
		l5=xx;
		l6=xx;
		tmp=0;
		for(int i=-l1;i<=l1;i++)
		{
			tmp=0;
			temp=(abs(i+2)^u[1][1])*wifi[1][1];
			if(temp+tmp>=ans)continue;
            else 
			{
                tmp+=temp;
                a=tmp;
            }
			for(int j=-l2;j<=l2;j++)
			{
                tmp=a;
				temp=(abs(j+3)^u[1][2])*wifi[1][2];
				if(tmp+temp>=ans)continue;
                else 
				{
                    tmp+=temp;
                    b=tmp;
                }
				for(int k=-l3;k<=l3;k++)
				{
                    tmp=b;
					temp=(abs(k+4)^u[1][3])*wifi[1][3];
					if(temp+tmp>=ans)continue;
                    else 
					{
                        tmp+=temp;
                        c=tmp;
                    }
					for(int z=-l4;z<=l4;z++)
					{
                        tmp=c;
						temp=(abs(z+3)^u[2][1])*wifi[2][1];
						if(temp+tmp>=ans)continue;
                        else
						{
                            tmp+=temp;
                            d=tmp;
                        }
						for(int p=-l5;p<=l5;p++)
						{
                            tmp=d;
							temp=(abs(p+4)^u[2][2])*wifi[2][2];
                            if(temp+tmp>=ans)continue;
                            else 
							{
                                tmp+=temp;
                                e=tmp;
                            }
							for(int q=-l6;q<=l6;q++)
							{
                                tmp=e;
								tmp+=(abs(q+5)^u[2][3])*wifi[2][3]+abs(i+j)+abs(j+k)+abs(z+p)+abs(p+q)+abs(i+z)+abs(j+p)+abs(k+q);
								if(tmp<ans)
									ans=tmp;
							}
						}
					}
				}
			}
		}
		printf("%d\n",ans);
	}
	else printf("0\n");
	return 0;
}




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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值