灯泡游戏

灯泡游戏

题目描述

有一个n行m列的矩阵,左上角坐标是(0,0),右下角坐标是(n-1,m-1)。每个格子有一个字符, “0”至“9”表示数字0至9,“a”至“z”表示数字10至35,“A”至“Z”表示数字36至61。矩阵的每个格子都有一个灯泡,刚开始除了左上角的灯泡是亮的,其他的灯泡都是灭的,刚开始你的得分是0。
游戏的过程是这样的:每次选一个灯泡是亮的格子X,同时选一个灯泡是灭的格子Y,而且要求格子X和格子Y是相邻的格子。这个步骤会使你的得分增加,增加的值是:格子X与格子Y代表的数字的差的绝对值。当然,这个步骤会使你选中的灭的灯泡变亮。重复上述操作,直到所有的灯泡都变成亮的。问你的最大得分是多少?

输入

第1行:两个整数n和m(1≤n,m≤50)。
  接下来是n行m列的矩阵。
  

输出

  一个整数,表示最大得分。
  

样例输入

2  2
05
aB

样例输出

69

提示

第一次选择:格子(0,0)和格子(1,0),得分是10-0=10;第二次选择:格子(1,0)和格子(1,1),得分是37-10:27;第三次选择:格子(1,1)和格子(0,1),得分是37-5=32,因此总得分是:10+27+32=69。

分析:其实是一棵最大生成树的长度,kruskal算法应该最快;

   我是每次暴力已用点的点集,找出相邻的没用过的最大的贡献点,更新答案,再把这个点放入点集;

   虽然重复做的次数很多,勉强还是水过了。。。

代码:

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <algorithm>
#include <climits>
#include <cstring>
#include <string>
#include <set>
#include <map>
#include <queue>
#include <stack>
#include <vector>
#include <list>
#include <ext/rope>
#define rep(i,m,n) for(i=m;i<=n;i++)
#define rsp(it,s) for(set<int>::iterator it=s.begin();it!=s.end();it++)
#define vi vector<int>
#define pii pair<int,int>
#define mod 1000000007
#define inf 0x3f3f3f3f
#define pb push_back
#define mp make_pair
#define fi first
#define se second
#define ll long long
#define pi acos(-1.0)
const int maxn=1e2+10;
const int dis[4][2]={{0,1},{-1,0},{0,-1},{1,0}};
using namespace std;
using namespace __gnu_cxx;
ll gcd(ll p,ll q){return q==0?p:gcd(q,p%q);}
ll qpow(ll p,ll q){ll f=1;while(q){if(q&1)f=f*p;p=p*p;q>>=1;}return f;}
int n,m,ans,vis[maxn][maxn];
char a[maxn][maxn];
set<pii >p;
int work(int x,int y)
{
    int u;
    if(a[x][y]>='0'&&a[x][y]<='9')u=a[x][y]-'0';
    else if(a[x][y]>='a'&&a[x][y]<='z')u=a[x][y]-'a'+10;
    else if(a[x][y]>='A'&&a[x][y]<='Z')u=a[x][y]-'A'+36;
    return u;
}
void dfs(int now)
{
    if(now==n*m)return;
    int ans_x,ans_y,ma=-1;
    for(pii q:p)
    {
        int x=q.fi,y=q.se;
        for(int i=0;i<4;i++)
        {
            int l=x+dis[i][0],r=y+dis[i][1];
            if(l>=0&&l<n&&r>=0&&r<m&&!vis[l][r])
                if(ma<abs(work(l,r)-work(x,y)))
                    ma=abs(work(l,r)-work(x,y)),ans_x=l,ans_y=r;
        }
    }
    ans+=ma;
    p.insert({ans_x,ans_y});
    vis[ans_x][ans_y]=1;
    dfs(now+1);
}
int main()
{
    int i,j,k,t;
    scanf("%d%d",&n,&m);
    rep(i,0,n-1)scanf("%s",a[i]);
    p.insert({0,0});
    vis[0][0]=1;
    dfs(1);
    printf("%d
",ans);
    //system ("pause");
    return 0;
}
原文地址:https://www.cnblogs.com/dyzll/p/5724319.html