灯泡游戏
题目描述
有一个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; }