XVII Open Cup named after E.V. Pankratiev Stage 14, Grand Prix of Tatarstan, Sunday, April 2, 2017 Problem L. Canonical duel

题目:Problem L. Canonical duel
Input file: standard input
Output file: standard output
Time limit: 2 seconds
Memory limit: 256 megabytes
In the game ?Canonical duel? board N × M is used. Some of the cells of the board contain turrets. A
turret is the unit with four cannons oriented to north, east, south and west. Each turret can shoot exactly
once. When turret is hit by the cannon of another turret, its activated. When turret is activated, all four
cannons shoot simultaneously, then self-destruction process causes the turret to disappear.
Given the board with some turrets. You may add exactly one turret on one of cells which does not
contains a turret and activate this new turret. Your goal is to destroy maximum number of turrets.
Input
First line of the input contains two positive integers N and M, does not exceeding 2000 — size of the
board.
Each of the next N lines contain exactly M chars: ‘+’ denotes that cell is occupied by a turret, and ‘.’
that cell is empty.
Output
In the first line print maximum number of existing turrets you may destroy, then in second line print two
space-separated integers — row and column of place where turret can be set. If it is impossible to destroy
ever one turret in such a way, print only one line containing a zero; if several solutions exist, print any of
them.
Examples

standard input standard output
3 4
++..
+...
..++
5
2 4
4 5
++...
..+..
....+
...++
5
4 1
3 3
+++
+++
+++
0

思路:

  用并查集维护每个点所能炸的点数量,然后处理出每个空位置上下左右最近的炮台的位置。之后枚举放置位置即可。

  

 1 #include <bits/stdc++.h>
 2
 3 using namespace std;
 4
 5 #define MP make_pair
 6 #define PB push_back
 7 typedef long long LL;
 8 typedef pair<int,int> PII;
 9 const double eps=1e-8;
10 const double pi=acos(-1.0);
11 const int K=1e6+7;
12 const int mod=1e9+7;
13
14 char ss[2005][2005];
15 int n,m,ans,ansx,ansy,f[4001000],cnt[4001000];
16 int dir[4001000][5],vis[4001000];
17 int idx(int i,int j)
18 {
19     if(i<1||j<1||i>n||j>m) return 0;
20     return (i-1)*m+j;
21 }
22 int fd(int x)
23 {
24     return f[x]==x?x:f[x]=fd(f[x]);
25 }
26 void join(int y,int x)
27 {
28     int fx=fd(x),fy=fd(y);
29     if(fx!=fy)
30         f[fy]=fx,cnt[fx]+=cnt[fy];
31 }
32 int main(void)
33 {
34     scanf("%d%d",&n,&m);
35     for(int i=1;i<=n;i++)
36         scanf("%s",&ss[i][1]);
37     for(int i=1;i<=n;i++)
38     for(int j=1;j<=m;j++)
39         f[idx(i,j)]=idx(i,j),cnt[idx(i,j)]=ss[i][j]==‘+‘;
40     for(int i=1;i<=n;i++)
41     for(int j=1;j<=m;j++)
42     {
43         dir[idx(i,j)][1]=ss[i-1][j]==‘+‘?idx(i-1,j):dir[idx(i-1,j)][1];
44         dir[idx(i,j)][3]=ss[i][j-1]==‘+‘?idx(i,j-1):dir[idx(i,j-1)][3];
45     }
46     for(int i=n;i;i--)
47     for(int j=m;j;j--)
48     {
49         dir[idx(i,j)][2]=ss[i+1][j]==‘+‘?idx(i+1,j):dir[idx(i+1,j)][2];
50         dir[idx(i,j)][4]=ss[i][j+1]==‘+‘?idx(i,j+1):dir[idx(i,j+1)][4];
51     }
52     for(int i=1;i<=n;i++)
53     for(int j=1;j<=m;j++)
54     if(ss[i][j]==‘+‘)
55     {
56         if(dir[idx(i,j)][1]) join(idx(i,j),dir[idx(i,j)][1]);
57         if(dir[idx(i,j)][3]) join(idx(i,j),dir[idx(i,j)][3]);
58         //printf("f[%d][%d]:%d\n",i,j,f[idx(i,j)]);
59     }
60 //    for(int i=1;i<=n;i++)
61 //    for(int j=1;j<=m;j++)
62 //    {
63 //        printf("dir[%d][%d]:",i,j);
64 //        for(int k=1;k<=4;k++)
65 //        printf("%d ",dir[idx(i,j)][k]);
66 //        printf("\n");
67 //    }
68 //    for(int i=1;i<=n;i++)
69 //    for(int j=1;j<=m;j++)
70 //    if(f[idx(i,j)]==idx(i,j))
71 //        printf("cnt[%d][%d]:%d\n",i,j,cnt[idx(i,j)]);
72     for(int i=1;i<=n;i++)
73     for(int j=1;j<=m;j++)
74     if(ss[i][j]==‘.‘)
75     {
76         int sum=0;
77         for(int k=1;k<=4;k++)
78         if(!vis[fd(dir[idx(i,j)][k])])
79             vis[fd(dir[idx(i,j)][k])]=1,sum+=cnt[fd(dir[idx(i,j)][k])];
80         for(int k=1;k<=4;k++)
81             vis[fd(dir[idx(i,j)][k])]=0;
82         //printf("sum:%d %d %d\n",i,j,sum);
83         if(sum>ans)
84             ans=sum,ansx=i,ansy=j;
85     }
86     if(ans) printf("%d\n%d %d\n",ans,ansx,ansy);
87     else printf("0\n");
88     return 0;
89 }
时间: 2024-08-06 11:54:11

XVII Open Cup named after E.V. Pankratiev Stage 14, Grand Prix of Tatarstan, Sunday, April 2, 2017 Problem L. Canonical duel的相关文章

XVII Open Cup named after E.V. Pankratiev Stage 14, Grand Prix of Tatarstan, Sunday, April 2, 2017 Problem F. Matrix Game

题目: Problem F. Matrix GameInput file: standard inputOutput file: standard inputTime limit: 1 secondMemory limit: 256 mebibytesAlice and Bob are playing the next game. Both have same matrix N × M filled with digits from 0 to 9.Alice cuts the matrix ve

XVII Open Cup named after E.V. Pankratiev Stage 14, Grand Prix of Tatarstan, Sunday, April 2, 2017 Problem J. Terminal

题目:Problem J. TerminalInput file: standard inputOutput file: standard inputTime limit: 2 secondsMemory limit: 256 mebibytesN programmers from M teams are waiting at the terminal of airport. There are two shuttles at the exitof terminal, each shuttle

XVII Open Cup named after E.V. Pankratiev Stage 14, Grand Prix of Tatarstan, Sunday, April 2, 2017 Problem A. Arithmetic Derivative

题目:Problem A. Arithmetic DerivativeInput file: standard inputOutput file: standard inputTime limit: 1 secondMemory limit: 256 mebibytesLets define an arithmetic derivative:? if p = 1 then p0 = 0;? if p is prime then p0 = 1;? if p is not prime then n0

【二分】【字符串哈希】【二分图最大匹配】【最大流】XVII Open Cup named after E.V. Pankratiev Stage 14, Grand Prix of Tatarstan, Sunday, April 2, 2017 Problem I. Minimum Prefix

给你n个字符串,问你最小的长度的前缀,使得每个字符串任意循环滑动之后,这些前缀都两两不同. 二分答案mid之后,将每个字符串长度为mid的循环子串都哈希出来,相当于对每个字符串,找一个与其他字符串所选定的子串不同的子串,是个二分图最大匹配的模型,可以匈牙利或者Dinic跑最大流看是否满流. 一个小优化是对于某个字符串,如果其所有不同的子串数量超过n,那么一定满足,可以直接删去. 卡常数,不能用set,map啥的,采取了用数组记录哈希值,排序后二分的手段进行去重和离散化. #include<cst

【二分图】【并查集】XVII Open Cup named after E.V. Pankratiev Stage 14, Grand Prix of Tatarstan, Sunday, April 2, 2017 Problem L. Canonical duel

给你一个网格(n<=2000,m<=2000),有一些炸弹,你可以选择一个空的位置,再放一个炸弹并将其引爆,一个炸弹爆炸后,其所在行和列的所有炸弹都会爆炸,连锁反应. 问你所能引爆的最多炸弹数. 转化成: 将行列当成点,炸弹当成边,然后你可以给这个二分图加1条边,问你最大的连通块的边的数量. 可以通过枚举所有可以建的边,通过并查集来尝试更新答案.由于一条边必然会让总度数+2,所以一个连通块的边数是所有点的度数之和/2. 并查集不必要动态维护集合的大小,一开始就建好并查集,提前统计好即可. 最后

【动态规划】【滚动数组】【bitset】XVII Open Cup named after E.V. Pankratiev Stage 14, Grand Prix of Tatarstan, Sunday, April 2, 2017 Problem J. Terminal

有两辆车,容量都为K,有n(10w)个人被划分成m(2k)组,依次上车,每个人上车花一秒.每一组的人都要上同一辆车,一辆车的等待时间是其停留时间*其载的人数,问最小的两辆车的总等待时间. 是f(i,j)表示前i组,j个人是否可行.w(i)表示第i组的人数. if f(i,j)==1 then f(i+1,j+w(i+1))=1. 这是个bitset可以做的事情,每次左移以后或上f(i-1)的bitset即可.其实可以滚动数组. 然后每更新一次bitset,求一下其最左侧的1的位置,就是对于第一辆

XVII Open Cup named after E.V. Pankratiev Stage 14, Grand Prix of Tatarstan, Sunday, April 2, 2017 Problem D. Clones and Treasures

题目:Problem D. Clones and TreasuresInput file: standard inputOutput file: standard outputTime limit: 1 secondMemory limit: 256 mebibytesThe magical treasury consists of n sequential rooms. Due to construction of treasury its impossible togo from room

【推导】【构造】XVII Open Cup named after E.V. Pankratiev Stage 14, Grand Prix of Tatarstan, Sunday, April 2, 2017 Problem E. Space Tourists

给你n,K,问你要选出最少几个长度为2的K进制数,才能让所有的n位K进制数删除n-2个元素后,所剩余的长度为2的子序列至少有一个是你所选定的. 如果n>K,那么根据抽屉原理,对于所有n位K进制数,必然会至少有1个数字出现2次或以上,所以00,11,...,K-1 K-1这样的数对是必选的. 对于其他的情况下,我们需要让他构造不出来n位不含重复数字的K进制数. 于是可以把K个数尽可能平均地分成n-1组,每一组内部让他们选出任意两个数都不合法,于是只能组间互相拼,这样他只能构造出最多n-1位的K进制

【推导】【贪心】XVII Open Cup named after E.V. Pankratiev Stage 14, Grand Prix of Tatarstan, Sunday, April 2, 2017 Problem D. Clones and Treasures

给你一行房间,有的是隐身药水,有的是守卫,有的是金币. 你可以任选起点,向右走,每经过一个药水或金币就拿走,每经过一个守卫必须消耗1个药水,问你最多得几个金币. 药水看成左括号,守卫看成右括号, 就从每个位置贪心地向右走,如果在 r 遇到不匹配,则把下一次的左端点置成r+1,接着走. O(n)即可. 因为如果把左端点放在上次的l和r之间,要么会发生不匹配,要么答案无法比上次走的更优. 队友代码: #include <iostream> #include <cstdio> #incl