1675: [Usaco2005 Feb]Rigging the Bovine Election 竞选划区(题解第二弹)
1675: [Usaco2005 Feb]Rigging the Bovine Election 竞选划区
Time Limit: 5 Sec Memory Limit: 64 MB
Submit: 198 Solved: 118
[Submit][Status][Discuss]
Description
It's election time. The farm is partitioned into a 5x5 grid of cow locations, each of which holds either a Holstein ('H') or Jersey ('J') cow. The Jerseys want to create a voting district of 7 contiguous (vertically or horizontally) cow locations such that the Jerseys outnumber the Holsteins. How many ways can this be done for the supplied grid?
农场被划分为5x5的格子,每个格子中都有一头奶牛,并且只有荷斯坦(标记为H)和杰尔西(标记为J)两个品种.如果一头奶牛在另一头上下左右四个格子中的任一格里,我们说它们相连. 奶牛要大选了.现在有一只杰尔西奶牛们想选择7头相连的奶牛,划成一个竞选区,使得其中它们品种的奶牛比荷斯坦的多. 要求你编写一个程序求出方案总数.
Input
* Lines 1..5: Each of the five lines contains five characters per line, each 'H' or 'J'. No spaces are present.
Output
* Line 1: The number of distinct districts of 7 connected cows such that the Jerseys outnumber the Holsteins in the district.
Sample Input
JHJHJ
HHHHH
HJHHJ
HHHHH
Sample Output
HINT
Source
Silver
题解:之前的题解中(传送门),采用的是\(O\left({25}^{7} \right)\)的简单暴力枚举,虽然能A,我一直认为还有更灵活的办法可以去做,于是有了这个第二篇题解
这次的思路是:每次先找一个点,然后向这个点的四周进行扩张,每一层dfs在原有的块的基础上再向外扩张一个,最终形成的块必然是7个连续的格子,应该能够起到比较好的优化效果——因为我每次选取扩张的点,都是通过动态维护当前块周围一圈的点来进行的,对于联通块而言,在地图内最多只能有15个周围的点,所以复杂度一下子降到了\(O\left({15}^{7} \right)\),并且完全不需要判断7个点是否构成一块。。。
以上是优点,但是这样一来仔细想想,缺点也十分明显——由于对于同样一个图形而言,可以由很多中扩张顺序可以形成,所以势必造成巨大的重复计算,这是个致命的伤。。。所以只好进行判重,所以只好又写了个双值哈希,确保一种选取情况对应一对唯一的哈希值,而对于一大堆乱七八糟的哈希值对,怎样判断是否存在呢?于是逗比的我又来个了平衡树进行查找,这样子算下来,时间复杂度 \(O\left({15}^{7}\times 7 Ans \log Ans \right)\)
1 /************************************************************** 2 Problem: 1675 3 User: HansBug 4 Language: Pascal 5 Result: Accepted 6 Time:2524 ms 7 Memory:2964 kb 8 ****************************************************************/ 9 10 const p=314159;q=951413; 11 type 12 pair=record 13 a0,b0:int64; 14 end; 15 var 16 i,j,k,l,m,n,head,tot,ans,av:longint; 17 lef,rig,fix:array[0..100000] of longint; 18 b:array[0..100000,1..2] of int64; 19 c,d:array[0..100,1..2] of longint; 20 a,e:array[0..10,0..10] of longint; 21 list:array[0..25,1..2] of int64; 22 ch:char; 23 procedure rt(var x:longint); 24 var l,f:longint; 25 begin 26 if (x=0) or (lef[x]=0) then exit; 27 f:=x;l:=lef[x]; 28 lef[f]:=rig[l]; 29 rig[l]:=f; 30 x:=l; 31 end; 32 procedure lt(var x:longint); 33 var r,f:longint; 34 begin 35 if (x=0) or (rig[x]=0) then exit; 36 f:=x;r:=rig[x]; 37 rig[f]:=lef[r]; 38 lef[r]:=f; 39 x:=r; 40 end; 41 function ins(var x:longint;y:longint):boolean; 42 begin 43 ins:=true; 44 if x=0 then 45 begin 46 x:=y; 47 exit; 48 end; 49 if (b[y,1]<b[x,1]) or ((b[y,1]=b[x,1]) and (b[y,2]<b[x,2])) then 50 begin 51 if lef[x]=0 then lef[x]:=y else ins:=ins(lef[x],y); 52 if fix[lef[x]]<fix[x] then rt(x); 53 end 54 else if (b[y,1]>b[x,1]) or ((b[y,1]=b[x,1]) and (b[y,2]>b[x,2])) then 55 begin 56 if rig[x]=0 then rig[x]:=y else ins:=ins(rig[x],y); 57 if fix[rig[x]]<fix[x] then lt(x); 58 end 59 else exit(false); 60 end; 61 function checkhash(t:pair):boolean; 62 begin 63 inc(tot); 64 b[tot,1]:=t.a0;b[tot,2]:=t.b0; 65 lef[tot]:=0;rig[tot]:=0;fix[tot]:=random(maxlongint); 66 checkhash:=ins(head,tot); 67 if not(checkhash) then dec(tot); 68 end; 69 function trans(x,y:longint):longint; 70 begin 71 trans:=(x-1)*5+y; 72 end; 73 function hashstate:pair; 74 var 75 i,j:longint;x,y:int64;t:pair; 76 begin 77 x:=0;y:=0; 78 for i:=1 to 7 do 79 begin 80 j:=trans(c[i,1],c[i,2]); 81 x:=(x+list[j,1]) mod q; 82 y:=(y+list[j,2]) mod p; 83 end; 84 t.a0:=x;t.b0:=y; 85 exit(t); 86 end; 87 procedure hashstartup; 88 var i:longint; 89 begin 90 list[0,1]:=1;list[0,2]:=1; 91 for i:=1 to 25 do 92 begin 93 list[i,1]:=(list[i-1,1]*p) mod q; 94 list[i,2]:=(list[i-1,2]*q) mod p; 95 end; 96 end; 97 procedure dfs(z:longint); 98 var i,j,k,l:longint; 99 begin 100 if z>7 then 101 begin 102 j:=0; 103 for i:=1 to 7 do inc(j,a[c[i,1],c[i,2]]); 104 if j<=3 then exit; 105 if checkhash(hashstate) then 106 begin 107 inc(ans); 108 end; 109 exit; 110 end; 111 l:=av; 112 for i:=1 to l do 113 begin 114 if e[d[i,1],d[i,2]]<>1 then continue; 115 c[z,1]:=d[i,1];c[z,2]:=d[i,2]; 116 e[d[i,1],d[i,2]]:=2; 117 if e[d[i,1]-1,d[i,2]]=0 then 118 begin 119 inc(av); 120 d[av,1]:=d[i,1]-1; 121 d[av,2]:=d[i,2]; 122 e[d[i,1]-1,d[i,2]]:=1; 123 end; 124 if e[d[i,1]+1,d[i,2]]=0 then 125 begin 126 inc(av); 127 d[av,1]:=d[i,1]+1; 128 d[av,2]:=d[i,2]; 129 e[d[i,1]+1,d[i,2]]:=1; 130 end; 131 if e[d[i,1],d[i,2]-1]=0 then 132 begin 133 inc(av); 134 d[av,1]:=d[i,1]; 135 d[av,2]:=d[i,2]-1; 136 e[d[i,1],d[i,2]-1]:=1; 137 end; 138 if e[d[i,1],d[i,2]+1]=0 then 139 begin 140 inc(av); 141 d[av,1]:=d[i,1]; 142 d[av,2]:=d[i,2]+1; 143 e[d[i,1],d[i,2]+1]:=1; 144 end; 145 dfs(z+1); 146 while av>l do 147 begin 148 e[d[av,1],d[av,2]]:=0; 149 d[av,1]:=0;d[av,2]:=0; 150 dec(av); 151 end; 152 e[d[i,1],d[i,2]]:=1; 153 end; 154 end; 155 begin 156 hashstartup; 157 tot:=0;head:=0;ans:=0;av:=0; 158 randomize; 159 fillchar(e,sizeof(e),0); 160 for i:=0 to 6 do 161 begin 162 e[i,0]:=1;e[0,i]:=1; 163 e[i,6]:=1;e[6,i]:=1; 164 end; 165 for i:=1 to 5 do 166 begin 167 for j:=1 to 5 do 168 begin 169 read(ch); 170 case upcase(ch) of 171 'H':a[i,j]:=0; 172 'J':a[i,j]:=1; 173 end; 174 end; 175 readln; 176 end; 177 for i:=1 to 5 do 178 for j:=1 to 5 do 179 begin 180 av:=0; 181 c[1,1]:=i;c[1,2]:=j; 182 if e[i-1,j]=0 then 183 begin 184 inc(av); 185 d[av,1]:=i-1;d[av,2]:=j; 186 e[i-1,j]:=1; 187 end; 188 if e[i+1,j]=0 then 189 begin 190 inc(av); 191 d[av,1]:=i+1;d[av,2]:=j; 192 e[i+1,j]:=1; 193 end; 194 if e[i,j-1]=0 then 195 begin 196 inc(av); 197 d[av,1]:=i;d[av,2]:=j-1; 198 e[i,j-1]:=1; 199 end; 200 if e[i,j+1]=0 then 201 begin 202 inc(av); 203 d[av,1]:=i;d[av,2]:=j+1; 204 e[i,j+1]:=1; 205 end; 206 e[i,j]:=2; 207 dfs(2); 208 while av>0 do 209 begin 210 e[d[av,1],d[av,2]]:=0; 211 d[av,1]:=0;d[av,2]:=0; 212 dec(av); 213 end; 214 e[i,j]:=0; 215 end; 216 writeln(ans); 217 readln; 218 end.
于是我很嗨皮的交了一下,结果是(上面的那个是这种新的算法,下面的是之前的纯暴力)
于是我再一次有了一种彻底被吓尿的赶脚QAQ,实在没想到这玩意常数会这么大,还有后来查了一下数据,事实证明在有些比较单调的图中,我程序的速度相当坑TT
所以只能优化啦——比如,我们不难发现每个块总有一个x值最小的点,于是可以在下面的搜索过程中限制扩张方向,只准向下、向右、向左(注意:不可以一一个点为基准,同时限制向下和向左,想想为什么^_^);还有,当当前的块里面已经出现4个H的时候,我觉得这个块就没任何继续下去的必要了对不——就算接下来全是J也没有用^_^;还有就是简单的常数优化了
于是再交了一次,结果如下(这两个都是优化过的,唯一的区别在于是否在过程和函数后面加了inline;)
于是,我终于战胜了原来的纯暴力,可实际上也不难发现一个问题——我后来写的优化程序有7KB还多,而简单的暴力只有2.5KB的样子,而且弄来弄去我最终的程序也才快了0.2s的样子,在考场上这根本不存在决定性作用。
显然,对这道题而言,还是朴素的暴力算法性价比高得多,尤其是考场上在极为有限的时间内,选择一个合适的方法尤其重要;不过我们还是不要为此导致不敢乱搞,脑洞还是要大开的^_^
优化代码:
1 /************************************************************** 2 Problem: 1675 3 User: HansBug 4 Language: Pascal 5 Result: Accepted 6 Time:1660 ms 7 Memory:2972 kb 8 ****************************************************************/ 9 10 const p=314159;q=951413; 11 type 12 pair=record 13 a0,b0:int64; 14 end; 15 var 16 i,j,k,l,m,n,head,tot,ans,av:longint; 17 lef,rig,fix:array[0..100000] of longint; 18 b:array[0..100000,1..2] of int64; 19 c,d:array[0..100,1..2] of longint; 20 a,e:array[0..10,0..10] of longint; 21 list:array[0..25,1..2] of int64; 22 ch:char; 23 procedure rt(var x:longint);inline; 24 var l,f:longint; 25 begin 26 if (x=0) or (lef[x]=0) then exit; 27 f:=x;l:=lef[x]; 28 lef[f]:=rig[l]; 29 rig[l]:=f; 30 x:=l; 31 end; 32 procedure lt(var x:longint);inline; 33 var r,f:longint; 34 begin 35 if (x=0) or (rig[x]=0) then exit; 36 f:=x;r:=rig[x]; 37 rig[f]:=lef[r]; 38 lef[r]:=f; 39 x:=r; 40 end; 41 function ins(var x:longint;y:longint):boolean;inline; 42 begin 43 ins:=true; 44 if x=0 then 45 begin 46 x:=y; 47 exit; 48 end; 49 if (b[y,1]<b[x,1]) or ((b[y,1]=b[x,1]) and (b[y,2]<b[x,2])) then 50 begin 51 if lef[x]=0 then lef[x]:=y else ins:=ins(lef[x],y); 52 if fix[lef[x]]<fix[x] then rt(x); 53 end 54 else if (b[y,1]>b[x,1]) or ((b[y,1]=b[x,1]) and (b[y,2]>b[x,2])) then 55 begin 56 if rig[x]=0 then rig[x]:=y else ins:=ins(rig[x],y); 57 if fix[rig[x]]<fix[x] then lt(x); 58 end 59 else exit(false); 60 end; 61 function checkhash(t:pair):boolean;inline; 62 begin 63 inc(tot); 64 b[tot,1]:=t.a0;b[tot,2]:=t.b0; 65 lef[tot]:=0;rig[tot]:=0;fix[tot]:=random(maxlongint); 66 checkhash:=ins(head,tot); 67 if not(checkhash) then dec(tot); 68 end; 69 function trans(x,y:longint):longint;inline; 70 begin 71 trans:=(x-1)*5+y; 72 end; 73 function hashstate:pair;inline; 74 var 75 i,j:longint;x,y:int64;t:pair; 76 begin 77 x:=0;y:=0; 78 for i:=1 to 7 do 79 begin 80 j:=trans(c[i,1],c[i,2]); 81 x:=(x+list[j,1]) mod q; 82 y:=(y+list[j,2]) mod p; 83 end; 84 t.a0:=x;t.b0:=y; 85 exit(t); 86 end; 87 procedure hashstartup;inline; 88 var i:longint; 89 begin 90 list[0,1]:=1;list[0,2]:=1; 91 for i:=1 to 25 do 92 begin 93 list[i,1]:=(list[i-1,1]*p) mod q; 94 list[i,2]:=(list[i-1,2]*q) mod p; 95 end; 96 end; 97 procedure dfs(z,t:longint);inline; 98 var i,j,k,l:longint; 99 begin 100 if (z-t)>4 then exit; 101 if z>7 then 102 begin 103 if checkhash(hashstate) then 104 begin 105 inc(ans); 106 end; 107 exit; 108 end; 109 l:=av; 110 for i:=1 to l do 111 begin 112 if e[d[i,1],d[i,2]]<>1 then continue; 113 c[z,1]:=d[i,1];c[z,2]:=d[i,2]; 114 e[d[i,1],d[i,2]]:=2; 115 if e[d[i,1]-1,d[i,2]]=0 then 116 begin 117 inc(av); 118 d[av,1]:=d[i,1]-1; 119 d[av,2]:=d[i,2]; 120 e[d[i,1]-1,d[i,2]]:=1; 121 end; 122 if e[d[i,1]+1,d[i,2]]=0 then 123 begin 124 inc(av); 125 d[av,1]:=d[i,1]+1; 126 d[av,2]:=d[i,2]; 127 e[d[i,1]+1,d[i,2]]:=1; 128 end; 129 if e[d[i,1],d[i,2]-1]=0 then 130 begin 131 inc(av); 132 d[av,1]:=d[i,1]; 133 d[av,2]:=d[i,2]-1; 134 e[d[i,1],d[i,2]-1]:=1; 135 end; 136 if e[d[i,1],d[i,2]+1]=0 then 137 begin 138 inc(av); 139 d[av,1]:=d[i,1]; 140 d[av,2]:=d[i,2]+1; 141 e[d[i,1],d[i,2]+1]:=1; 142 end; 143 dfs(z+1,t+a[d[i,1],d[i,2]]); 144 while av>l do 145 begin 146 e[d[av,1],d[av,2]]:=0; 147 d[av,1]:=0;d[av,2]:=0; 148 dec(av); 149 end; 150 e[d[i,1],d[i,2]]:=1; 151 end; 152 end; 153 begin 154 hashstartup; 155 tot:=0;head:=0;ans:=0;av:=0; 156 randomize; 157 fillchar(e,sizeof(e),0); 158 for i:=0 to 6 do 159 begin 160 e[i,0]:=1;e[0,i]:=1; 161 e[i,6]:=1;e[6,i]:=1; 162 end; 163 for i:=1 to 5 do 164 begin 165 for j:=1 to 5 do 166 begin 167 read(ch); 168 case upcase(ch) of 169 'H':a[i,j]:=0; 170 'J':a[i,j]:=1; 171 end; 172 end; 173 readln; 174 end; 175 for i:=1 to 5 do 176 begin 177 for j:=1 to 5 do c[i-1,j]:=1; 178 for j:=1 to 5 do 179 begin 180 av:=0; 181 c[1,1]:=i;c[1,2]:=j; 182 if e[i-1,j]=0 then 183 begin 184 inc(av); 185 d[av,1]:=i-1;d[av,2]:=j; 186 e[i-1,j]:=1; 187 end; 188 if e[i+1,j]=0 then 189 begin 190 inc(av); 191 d[av,1]:=i+1;d[av,2]:=j; 192 e[i+1,j]:=1; 193 end; 194 if e[i,j-1]=0 then 195 begin 196 inc(av); 197 d[av,1]:=i;d[av,2]:=j-1; 198 e[i,j-1]:=1; 199 end; 200 if e[i,j+1]=0 then 201 begin 202 inc(av); 203 d[av,1]:=i;d[av,2]:=j+1; 204 e[i,j+1]:=1; 205 end; 206 e[i,j]:=2; 207 dfs(2,a[i,j]); 208 while av>0 do 209 begin 210 e[d[av,1],d[av,2]]:=0; 211 d[av,1]:=0;d[av,2]:=0; 212 dec(av); 213 end; 214 e[i,j]:=0; 215 end; 216 end; 217 writeln(ans); 218 readln; 219 end.
转载于:https://www.cnblogs.com/HansBug/p/4414164.html
1675: [Usaco2005 Feb]Rigging the Bovine Election 竞选划区(题解第二弹)相关推荐
- bzoj 1675: [Usaco2005 Feb]Rigging the Bovine Election 竞选划区(暴力)
1675: [Usaco2005 Feb]Rigging the Bovine Election 竞选划区 Time Limit: 5 Sec Memory Limit: 64 MB Submit: ...
- BZOJ 1734: [Usaco2005 feb]Aggressive cows 愤怒的牛( 二分答案 )
最小最大...又是经典的二分答案做法.. -------------------------------------------------------------------------- #inc ...
- bzoj 3392: [Usaco2005 Feb]Part Acquisition 交易(最短路)
3392: [Usaco2005 Feb]Part Acquisition 交易 Time Limit: 5 Sec Memory Limit: 128 MB Submit: 191 Solved ...
- bzoj 1676: [Usaco2005 Feb]Feed Accounting 饲料计算(差分)
1676: [Usaco2005 Feb]Feed Accounting 饲料计算 Time Limit: 5 Sec Memory Limit: 64 MB Submit: 252 Solved ...
- 【差分】bzoj 1676 [Usaco2005 Feb]Feed Accounting 饲料计算
题目的建模意思是什么呢? 每个奶牛从a点开始吃,从b+1点就停止吃.这就是间接告诉你这两点组成一个区间,需要差分序列. 之后对差分的序列求前缀和(计算每天的粮草的消耗量), 之后对于消耗的粮草,我们倒 ...
- BZOJ1734: [Usaco2005 Feb]Aggressive cows 愤怒的牛
[传送门:BZOJ1734] 简要题意: 约翰有N 间牛棚,这些牛棚坐落在一条直线上,第i 间牛棚位于坐标Xi 的位置.他要把C 头 奶牛安排在这些牛棚里.每间牛棚最多可以放一头奶牛,也可以空着.这些 ...
- BZOJ1733: [Usaco2005 feb]Secret Milking Machine 神秘的挤奶机
n<=200个点m<=40000条边无向图,求 t次走不经过同条边的路径从1到n的经过的边的最大值 的最小值. 最大值最小--二分,t次不重边路径--边权1的最大流. 1 #inc ...
- 杭电oj题目题型分类(转)
1001 整数求和 水题 1002 C语言实验题--两个数比较 水题 1003 1.2.3.4.5... 简单题 1004 渊子赛马 排序+贪心的方法归并 1005 Hero In Maze 广度搜索 ...
- HDOJ题目分类大全
版权声明:本文为博主原创文章,欢迎转载,转载请注明本文链接! https://blog.csdn.net/qq_38238041/article/details/78178043 杭电里面有很多题目, ...
最新文章
- 031_mysql事务的安全隐患
- H.264中的量化过程
- 查看linux机器性能,Unix Linux 查看机器性能
- 语音编解码技术演进和应用选型
- 重置手机_【轻松办税】ITS客户端申报密码重置不会操作?看过来,3分钟包你会!...
- shell执行perl_【编程技巧(一)】在Perl、Shell和Python中传参与输出帮助文档
- java list 字段去重_java list 根据对象一个字段去重
- win下python和opencv安装
- 360公司2019秋季校园招聘内部推荐启动啦!!!
- Mac Big Sur右上角时间变灰的解决方法
- highcharts插件使用总结和开发中遇到的问题及解决办法
- 精品微信小程序班级打卡系统+后台管理系统|前后分离VUE
- 基于matlab计算机视觉的葡萄检测分级系统
- JDY-24M主机使用手册
- 百度云盘照片导入华为相册里_百度网盘传送列表怎样导入手机相册_手机百度网盘下载到相册...
- 故宫景点功课4:太和殿院落下
- iOS中assign和weak修饰符的区别
- 转载出去:http://blog.csdn.net/han_xiaoyang/article/details/11969497
- 探索隐藏在冰山下的自己
- 基于matlab的现代通信原理应用
热门文章
- 这个图片转文字功能搞一下?还好这个开源项目救了我!
- 天池NLP大赛来了!
- 厦门大学宋宁宇:统计学专业到蚂蚁风控岗!
- 30万奖金!首个有阿里技术培训支持,让AI落定场景应用的赛事!
- Uber准备放弃自动驾驶,转手卖给前谷歌无人车CTO,估值曾被孙正义炒到72.5亿美元...
- 他们为什么选择中科大少年班?官方公布48名新生名单,有人因偶像曹原,有人只是不想经历高三...
- 7天试学计划 | 人工智能核心能力课程招生
- 清华北大亚洲第一第二!就在刚刚,2020 泰晤士亚洲大学排名公布!
- 那个14岁上大学、17岁读博、24岁成教授的天才神童,如今怎样了?
- 文件列表出现分页按钮