题目描述

流行的跳棋游戏是在一个有m*n个方格的长方形棋盘上玩的。棋盘起初全部被动物或障碍物占满了。在一个方格中,‘X’表示一个障碍物,一个‘0’~‘9’的个位数字表示一个不同种类的动物,相同的个位数字表示相同种类的动物。一对动物只有当它们属于同一种类时才可以被消去。消去之后,他们所占的方格就成为空方格,直到游戏结束。要消去一对动物的前提条件是:这对候选动物所在的方格必须相邻,或它们之间存在一条通路。棋盘上一个方格只和其上下左右的方格相邻。一条通路是由一串相邻的空方格组成。路的长度则是通路中空方格的数目。你要输出可被消去的动物的最多对数,以及在此操作过程中,最小的通路长度总和。

数据范围

N,M<=5

解法

暴力+剪枝

正确性可以保证,时间效率较低;

可以考虑牺牲点正确性以提高时间效率。

A*

正确性和时间效率取决于估价函数。

带策略的暴力

正确性勉强,时间效率卡常数;

贪心

正确性无法保证,时间效率高;

所以可以考虑牺牲时间效率,多次求解求最优。

代码

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
using namespace std;
const char* fin="pair.in";
const char* fout="pair.out";
const int inf=0x7fffffff;
const int maxn=13,maxm=maxn*maxn;
const int h[4][2]={{1,0},{-1,0},{0,1},{0,-1}};
int n,m,i,j,k,maxx,ans1,ans2,interesting=5,hx,hy,ans3,ans4;
char a[maxn][maxn];
bool bz[maxn][maxn];
int b[maxm][2],head,tail,c[6];
int f[maxn][maxn];
int heavy(int x,int y){
return max(abs(x-hx),abs(y-hy));
}
void add(int x,int y,int z,int awful){
if (z>=f[x][y] || (!bz[x][y] && awful==0) || a[x][y]=='X') return ;
b[++tail][0]=x;
b[tail][1]=y;
f[x][y]=z;
}
int getdis(int x,int y,int u,int v){
int i,j,k,ans=inf;
memset(f,127,sizeof(f));
head=tail=0;
add(x,y,0,1);
while (head++<tail){
for (i=0;i<4;i++){
j=b[head][0]+h[i][0];
k=b[head][1]+h[i][1];
if (j>0 && j<=n && k>0 && k<=m)
if (j==u && k==v) ans=min(f[b[head][0]][b[head][1]],ans);
else add(j,k,f[b[head][0]][b[head][1]]+1,0);
}
}
return ans;
}
void work(int x,int y){
int i,j,k,minx=10000,mnid[2],mminx=inf;
for (i=1;i<=n;i++)
for (j=1;j<=m;j++)
if (!bz[i][j] && a[i][j]==a[x][y]){
if (x==i && y==j) continue;
k=getdis(x,y,i,j);
if (k<minx || k==minx && heavy(i,j)<mminx){
minx=k;
mminx=heavy(i,j);
mnid[0]=i;
mnid[1]=j;
}
}
if (minx==10000) return;
else{
/*ans1++;
ans2+=minx;
bz[x][y]=true;
bz[mnid[0]][mnid[1]]=true;*/
if (c[1]>minx){
c[1]=minx;
c[2]=x;
c[3]=y;
c[4]=mnid[0];
c[5]=mnid[1];
}
}
}
void solve(int v){
int i,j,k;
while (1){
c[1]=10000;
for (i=v;i<=n-v+1;i++) if (!bz[i][m-v+1] && a[i][m-v+1]!='X') work(i,m-v+1);
for (i=m-v+1;i>=v;i--) if (!bz[i][v] && a[i][v]!='X') work(i,v);
for (i=v;i<=n-v+1;i++) if (!bz[n-v+1][i] && a[n-v+1][i]!='X') work(n-v+1,i);
for (i=m-v+1;i>=v;i--) if (!bz[v][i] && a[v][i]!='X') work(v,i);
if (c[1]<10000){
bz[c[2]][c[3]]=true;
bz[c[4]][c[5]]=true;
ans1++;
ans2+=c[1];
}else break;
}
}
int main(){
freopen(fin,"r",stdin);
freopen(fout,"w",stdout);
scanf("%d%d",&n,&m);
for (i=1;i<=n;i++) scanf("%s",a[i]+1);
maxx=min((n+1)/2,(m+1)/2);
for (hx=1;hx<=n;hx++)
for (hy=1;hy<=m;hy++){
memset(bz,0,sizeof(bz));
ans1=ans2=0;
for (i=1;i<=maxx;i++){
for (j=i;j;j--){
solve(j);
}
}
if (ans1>ans3 || ans1==ans3 && ans2<ans4){
ans3=ans1;
ans4=ans2;
}
}
for (hx=1;hx<=n;hx++)
for (hy=1;hy<=m;hy++){
memset(bz,0,sizeof(bz));
ans1=ans2=0;
for (i=maxx;i;i--){
for (j=i;j;j--){
solve(j);
}
}
if (ans1>ans3 || ans1==ans3 && ans2<ans4){
ans3=ans1;
ans4=ans2;
}
}
for (hx=1;hx<=n;hx++)
for (hy=1;hy<=m;hy++){
memset(bz,0,sizeof(bz));
ans1=ans2=0;
for (i=maxx;i;i--){
for (j=1;j<=maxx;j++){
solve(j);
}
}
if (ans1>ans3 || ans1==ans3 && ans2<ans4){
ans3=ans1;
ans4=ans2;
}
}
for (hx=1;hx<=n;hx++)
for (hy=1;hy<=m;hy++){
memset(bz,0,sizeof(bz));
ans1=ans2=0;
for (i=1;i<=maxx;i++){
for (j=i;j;j--){
solve(j);
}
}
if (ans1>ans3 || ans1==ans3 && ans2<ans4){
ans3=ans1;
ans4=ans2;
}
}
printf("%d %d",ans3,ans4);
return 0;
}

启发

这种题常出现在NOIP提高组的压轴题,

往往没有稳定复杂度的算法。

此时就要考虑上述几种做法,进行取舍,以骗得最高的分数。

大致上就是平衡时间效率正确性


此外还有考虑编程复杂度的问题,以我的观点:

贪心的编程复杂度最简单,也最容易调试;

因为贪心的每一次操作具有后效性。

【JZOJ4824】【NOIP2016提高A组集训第1场10.29】配对游戏的更多相关文章

  1. 【NOIP2016提高A组集训第1场10.29】配对游戏

    题目 流行的跳棋游戏是在一个有mn个方格的长方形棋盘上玩的.棋盘起初全部被动物或障碍物占满了.在一个方格中,'X'表示一个障碍物,一个'0'-'9'的个位数字表示一个不同种类的动物,相同的个位数字表示 ...

  2. 【NOIP2016提高A组集训第1场10.29】完美标号

    题目 给定M个二元组(A_i, B_i),求X_1, ..., X_N满足:对于任意(A_i, B_i),有|X_{A_i} - X_{B_i}| = 1成立. 分析 显然,对于二元组(x,y),X_ ...

  3. 【NOIP2016提高A组集训第3场10.31】高维宇宙

    题解 分析 因为只有奇数和偶数配对才有可能得出质数, 暴力求出每一对\(a_i+a_j\)为质数,将其中的奇数想偶数连一条边. 二分图匹配,匈牙利算法. #include <cmath> ...

  4. 【JZOJ4831】【NOIP2016提高A组集训第3场10.31】方程式

    题目描述 数据范围 解法 枚举根之后,使用大除法. 代码 #include<stdio.h> #include<iostream> #include<string.h&g ...

  5. 【JZOJ4832】【NOIP2016提高A组集训第3场10.31】高维宇宙

    题目描述 数据范围 解法 由于大于4的素数只有可能由奇数和偶数的和得出. 所以根据数的奇偶性可以分出两类数奇数和偶数. 奇数之间不会相互匹配,偶数之间也不会相互匹配. 那么原问题转化为二分图最大匹配. ...

  6. 【JZOJ4833】【NOIP2016提高A组集训第3场10.31】Mahjong

    题目描述 解法 搜索. 代码 #include<stdio.h> #include<iostream> #include<string.h> #include< ...

  7. JZOJ 【NOIP2016提高A组集训第16场11.15】兔子

    JZOJ [NOIP2016提高A组集训第16场11.15]兔子 题目 Description 在一片草原上有N个兔子窝,每个窝里住着一只兔子,有M条路径连接这些窝.更特殊地是,至多只有一个兔子窝有3 ...

  8. JZOJ 【NOIP2016提高A组集训第16场11.15】SJR的直线

    JZOJ [NOIP2016提高A组集训第16场11.15]SJR的直线 题目 Description Input Output Sample Input 6 0 1 0 -5 3 0 -5 -2 2 ...

  9. 【NOIP2016提高A组集训第4场11.1】平衡的子集

    题目 夏令营有N个人,每个人的力气为M(i).请大家从这N个人中选出若干人,如果这些人可以分成两组且两组力气之和完全相等,则称为一个合法的选法,问有多少种合法的选法? 分析 如果暴力枚举每个人被分到哪 ...

随机推荐

  1. Java文件写入

    一,FileWritter写入文件 FileWritter, 字符流写入字符到文件.默认情况下,它会使用新的内容取代所有现有的内容,然而,当指定一个true (布尔)值作为FileWritter构造函 ...

  2. Tensorboard在Win7下chrome无论如何无法连接的情况

    后记:其实发现原因后感觉自己很蠢,是自己开了一个软件叫adsafe,会屏蔽一些东西,所以我拼命的用自己的电脑ip都连不上,换成回环地址就好了,把软件关了也可以. 在无数种尝试后,终于在stackove ...

  3. Odoo 中的widget

    many2many_tags one2many_list selection progressbar selection statusbar handle monetary mail_thread s ...

  4. linux下定位文件

    参考:http://www.cnblogs.com/ccode/p/4033088.html: 在linux命令行模式下,经常会遇到定位文件的问题,这时候采用locate和find都是可以的,下面简述 ...

  5. BZOJ 1099 树网的核

    题面 解题思路 搞了三个多小时.... noip时的数据很水,直接暴力n^3过. 我们考虑优化,首先可以贪心,我们要在直径上选肯定越插长越好,所以n^2其实就可以解决.但这还不够,根据直径的最长性,我 ...

  6. Leetcode50. Pow(x, n)(快速幂)

    实现 pow(x, n) ,即计算 x 的 n 次幂函数. 示例 1: 输入: 2.00000, 10 输出: 1024.00000 示例 2: 输入: 2.10000, 3 输出: 9.26100 ...

  7. 用 Python 写一个 NoSQL 数据库Python

    NoSQL 这个词在近些年正变得随处可见. 但是到底 “NoSQL” 指的是什么? 它是如何并且为什么这么有用? 在本文, 我们将会通过纯 Python (我比较喜欢叫它, “轻结构化的伪代码”) 写 ...

  8. 使用log4j打印日志

    在项目中我们必不可少需要打印日志,通过日志我们可以查看系统的运行状态是否正常,当程序出现异常的时候,我们也可以通过查看日志来定位问题的位置,给程序员的工作带来了极大的便利. 以下这边博客的内容是我从一 ...

  9. 如何制作可以在 MaxCompute 上使用的 crcmod

    之前我们介绍过在 PyODPS DataFrame 中使用三方包.对于二进制包而言,MaxCompute 要求使用包名包含 cp27-cp27m 的 Wheel 包.但对于部分长时间未更新的包,例如 ...

  10. web前端学习(二)html学习笔记部分(2)-- 改良的元素(input元素等等)

    1.2.5  HTML5 改良的 input 元素的种类 1.2.5.1  新增的input元素种类中的改良与增加 input 元素的种类 (1) 新增的input元素种类中的url类型.email类 ...