题目链接:http://codeforces.com/contest/463/problem/C

题目意思:要在一个 n * n 大小的棋盘上放置两个bishop,bishop可以攻击的所有位置是包括经过bishop 位置的两条成90度的对角线所经过的所有坐标点。每个坐标点都有数字在上面,放置一个bishop后,可以获得能被放置的bishop攻击的所有坐标点的数字的和。但是有一个条件限制:同一个坐标点不能被两个bishop攻击,也就是四条对角线的交点不能是棋盘上的某个坐标点。求出在该条件限制下,两个bishop的放置位置以及能获得的最大和。

首先没有看到这个条件wa了很多次: place two bishops on the chessboard in such a way that there is no cell that is attacked by both of them。

好不容易看到之后,就各种TLE了,原来是读入问题!!!!涨姿势勒= =

可喜的是,原来自己最开始的做法是可取的,不过都是因为读入问题。

先介绍作者的灵活高效版:

先看一个图:

作者的做法有两个巧妙之处:

(1)求 bishop 能够攻击的所有坐标点的和,简而言之就是一个坐标点的两条对角线的和。

  设两个数组d1[],d2[],用于保存两种方向下的对角线总和。(虚线部分标明了方向)。d1[]数组是通过d1[i+j] += board[i][j] 来算的,而 d2是这样:d2[i-j+n] += board[i][j]。

如果要求某个特定的坐标(i, j)的对角线和,那么就是d1[i+j] + d2[i-j+n] - board[i][j] ,之所以要减去board是因为每个坐标点的和都被重复算多了一次。

(2)判断攻击的方法

假设 bishop1 坐标为(i1, j1),bishop2 为(i2, j2),如果( i1 + j1),( i2 + j2) 同奇或同偶,那么就存在某一个坐标点同时被两个bishop 攻击!

所以要满足不存在某个坐标同时被两个bishop 攻击,就需要(i1 + j1) 和 (i2+j2) 处于一奇一偶的情况。那么奇数找一个最大值,偶数的话又找一个最大值,加起来就是两个bishop放置后能够获得的最大和了。

Time:  217ms     Memory:  31400KB

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <cstdlib>
 4 #include <cstring>
 5 using namespace std;
 6
 7 typedef long long LL;
 8 const int maxn = 2000 + 2;
 9
10 LL board[maxn][maxn];
11 LL d1[maxn<<1], d2[maxn<<1];
12 pair<int, int> ans[2];
13 LL tmp[2];
14
15 inline LL read()   // 这个读入是避免TLE的关键
16 {
17     int x = 0, f = 1;
18     char ch = getchar();
19     while (ch >= '0' && ch <= '9')
20     {
21         x = 10*x + ch-'0';
22         ch = getchar();
23     }
24     return (LL)(x * f);
25 }
26
27 int main()
28 {
29     int n, x1, x2, y1, y2;
30     while (scanf("%d", &n) != EOF)
31     {
32         memset(d1, 0, sizeof(d1));
33         memset(d2, 0, sizeof(d2));
34         getchar();   // 不能省!n之后有个空格= =
35         for (int i = 1; i <= n; i++)
36         {
37             for (int j = 1; j <= n; j++)
38             {
39                  board[i][j] = read();
40                  d1[i+j] += board[i][j];
41                  d2[i-j+n] += board[i][j];
42             }
43         }
44         tmp[0] = tmp[1] = -1;    // 0也可以,但是后面要>=,防止多次被替换还是-1好,省时一点吧
45         for (int i = 1; i <= n; i++)
46         {
47             for (int j = 1; j <= n; j++)
48             {
49                 LL val = d1[i+j] + d2[i-j+n] - board[i][j];
50                 if (val > tmp[(i+j)&1])
51                 {
52                     tmp[(i+j)&1] = val;
53                     ans[(i+j)&1].first = i;
54                     ans[(i+j)&1].second = j;
55                 }
56             }
57         }
58         printf("%lld\n", tmp[0] + tmp[1]);
59         printf("%d %d %d %d\n", ans[0].first, ans[0].second, ans[1].first, ans[1].second);
60     }
61     return 0;
62 }

View Code

接下来就是我的做法(大家可以忽略)

求对角线的和的时候,我是采取从第1行,第1列,最后1列出发来求得的,最后还是需要减去board[i][j],代码量好大,因为太多重复 = =

至于判断攻击,除了利用abs函数(恰好对角线),还利用了之前做的一条 cf370A 的 Rook, Bishop  and King的做法啦—— 判断Bishop 步数。

毕竟自己写的,留下纪念吧 = =

真是又长又耗时啊~~

Time:  1122ms     Memory:  125504KB

  1 #include <iostream>
  2 #include <cstdio>
  3 #include <cstdlib>
  4 #include <cstring>
  5 #include <cmath>
  6 #include <algorithm>
  7 using namespace std;
  8
  9 typedef long long LL;
 10 const int maxn = 2000 + 2;
 11
 12 struct node
 13 {
 14     LL s;
 15     int x, y;
 16     bool operator < (const node& a) const
 17     {
 18         return s < a.s;
 19     }
 20 }num[maxn*maxn];
 21
 22 LL board[maxn][maxn];
 23 LL sum[maxn][maxn];
 24
 25 inline LL read()   // 这个读入是避免TLE的关键
 26 {
 27     int x = 0, f = 1;
 28     char ch = getchar();
 29     while (ch >= '0' && ch <= '9')
 30     {
 31         x = 10*x + ch-'0';
 32         ch = getchar();
 33     }
 34     return (LL)(x * f);
 35 }
 36
 37 int main()
 38 {
 39     int n;
 40     while (scanf("%d", &n) != EOF)
 41     {
 42         getchar();
 43         for (int i = 1; i <= n; i++)
 44         {
 45             for (int j = 1; j <= n; j++)
 46                 board[i][j] = (LL)read();
 47         }
 48         memset(sum, 0, sizeof(sum));
 49         // 第 1 行
 50         int i = 1;
 51         for (int j = 1; j <= n; j++)
 52         {
 53             LL ss = 0;
 54             int ti = i;
 55             int tj = j;   // 右下
 56             while (ti <= n && tj <= n)
 57             {
 58                 ss += board[ti][tj];
 59                 ti++;
 60                 tj++;
 61             }
 62             ti = i;
 63             tj = j;
 64             while (ti <= n && tj <= n)
 65             {
 66                 sum[ti][tj] += ss;
 67                 ti++;
 68                 tj++;
 69             }
 70             ti = i;
 71             tj = j;  // 左下
 72             ss = 0;
 73             while (ti <= n && tj >= 1)
 74             {
 75                 ss += board[ti][tj];
 76                 ti++;
 77                 tj--;
 78             }
 79             ti = i;
 80             tj = j;
 81             while (ti <= n && tj >= 1)
 82             {
 83                 sum[ti][tj] += ss;
 84                 ti++;
 85                 tj--;
 86             }
 87         }
 88         // 第 1 列
 89         int j = 1;
 90         for (int i = 2; i <= n; i++)
 91         {
 92             LL ss = 0;
 93             int ti = i;
 94             int tj = j;
 95             while (ti <= n && tj <= n)
 96             {
 97                 ss += board[ti][tj];
 98                 ti++;
 99                 tj++;
100             }
101
102             ti = i;
103             tj = j;
104             while (ti <= n && tj <= n)
105             {
106                 sum[ti][tj] += ss;
107                 ti++;
108                 tj++;
109             }
110         }
111         j = n;
112         for (int i = 2; i <= n; i++)
113         {
114             LL ss = 0;
115             int ti = i;
116             int tj = j;
117             while (ti <= n && tj >= 1)
118             {
119                 ss += board[ti][tj];
120                 ti++;
121                 tj--;
122             }
123             ti = i;
124             tj = j;
125             while (ti <= n && tj >= 1)
126             {
127                 sum[ti][tj] += ss;
128                 ti++;
129                 tj--;
130             }
131         }
132         int cnt = 0;
133         for (int i = 1; i <= n; i++)
134         {
135             for (int j = 1; j <= n; j++)
136             {
137                  num[cnt].x = i;
138                  num[cnt].y = j;
139                  num[cnt++].s = sum[i][j] - board[i][j];
140             }
141         }
142         int flag = 0;
143         LL maxsum;
144         int x1, y1, x2, y2;
145         sort(num, num+cnt);
146         for (int i = cnt-1; i >= 0 && !flag; i--)
147         {
148             for (int j = i-1; j >= 0 && !flag; j--)
149             {
150                 int t1 = num[i].x + num[i].y;
151                 int t2 = abs(num[j].x - num[j].y);
152                 if ((t1 + t2) % 2 == 0)
153                     continue;
154                 if (abs(num[i].x-num[j].x) != abs(num[i].y - num[j].y))
155                 {
156                     flag = 1;
157                     x1 = num[i].x, x2 = num[j].x;
158                     y1 = num[i].y, y2 = num[j].y;
159                     maxsum = num[i].s + num[j].s;
160                     break;
161                 }
162             }
163         }
164         printf("%lld\n", maxsum);
165         printf("%d %d %d %d\n", x1, y1, x2, y2);
166     }
167     return 0;
168 }

View Code

转载于:https://www.cnblogs.com/windysai/p/3950496.html

codeforces 463C. Gargari and Bishops 解题报告相关推荐

  1. Codeforces Round #264 (Div. 2) 解题报告

    Source:  http://codeforces.com/contest/463 打得比较差..第三题想写nlgn的,结果调了很久又wa,以为写挫,过了很久发现做法有问题..最后两题惨淡收场.第四 ...

  2. CodeForce 463C Gargari and Bishops(贪心+暴力)

    Gargari and Bishops time limit per test 3 seconds memory limit per test 256 megabytes input standard ...

  3. CodeCraft-19 and Codeforces Round #537 (Div. 2)解题报告

    Codeforces Round #537 (Div. 2) 题解报告 A. Superhero Transformation 题意 问能否通过把辅音字母换成另一个辅音字母,元音字母换成另一个元音字母 ...

  4. Codeforces Round #702 (Div. 3)解题报告

    Codeforces Round #702 (Div. 3) 全部题解 读错题意,写了半天真是心态爆炸,总的来看这次题目不难的. A. Dense Array http://codeforces.co ...

  5. codeforces A. Jeff and Digits 解题报告

    题目链接:http://codeforces.com/problemset/problem/352/A 题目意思:给定一个只有0或5组成的序列,你要重新编排这个序列(当然你可以不取尽这些数字),使得这 ...

  6. codeforces B. Eight Point Sets 解题报告

    题目链接:http://codeforces.com/problemset/problem/334/B 一开始看到题目,有点怯,理解了题目后,其实并不难.这句话是突破口 three distinct ...

  7. codeforces 450B. Jzzhu and Sequences 解题报告

    题目链接:http://codeforces.com/problemset/problem/450/B 题目意思:给出 f1 和 f2 的值,以及n,根据公式:fi = fi-1 + fi+1,求出f ...

  8. codeforces 435 B. Pasha Maximizes 解题报告

    题目链接:http://codeforces.com/problemset/problem/435/B 题目意思:给出一个最多为18位的数,可以通过对相邻两个数字进行交换,最多交换 k 次,问交换 k ...

  9. codeforces B. Fox and Cross 解题报告

    题目链接:http://codeforces.com/problemset/problem/389/B 题目意思:给出一个由n行n列组成的board,其中'#'表示的一片地方恰好能画满十字架,画满的意 ...

最新文章

  1. 如何为Pyramid添加Middleware
  2. 火星上真的有液态水?!欧洲科学家新发现登上《自然·天文学》
  3. 使用微软WPF技术开发产品优势究竟在那里
  4. Python——中国大学MOOC——神经网络与深度学习——Matblotlib绘图基础
  5. 2014年12月15日报
  6. 9.20PMP每日一题
  7. 马尔可夫决策过程(MDP)
  8. IS-IS详解(三)——IS-IS 报文结构与功能
  9. Unix/Linux环境C编程入门教程(24) MySQL 5.7.4 for Red Hat Enterprise 7(RHEL7)的安装
  10. Java入门教程——下载JAVA
  11. 黄山旅游自助攻略住宿行程路线篇
  12. Maya中英文对照表(四)
  13. 小米mini路由器,刷openwrt,制作usb打印机服务器
  14. pythonpdf识别文字软件_如何使用Python进行PDF图片识别OCR
  15. HTML5调整图像垂直边距,77.通过vspace和hspace属性可以分别调整图像的垂直边距和水平边距。()()...
  16. 卡方检验检验水准矫正_医学统计学 第七章 卡方检验
  17. console,控制台也能玩出花样(console操作大全)
  18. c语言 整数拆分,C++ 整数拆分方法详解
  19. 集成学习(含常用案列)
  20. oracle 空值排序,排在最前面或者最后面

热门文章

  1. 灰色关联度分析_数学建模|关联分析之术|灰度预测模型预备知识
  2. python中合法的二进制整数_python:求整数的二进制表示
  3. 【算法】剑指 Offer 17. 打印从1到最大的n位数
  4. 【kafka】kafka 中 消息 record 格式
  5. 【es】使用ElasticSearch的44条建议 性能优化
  6. 【java】java 1.8 之 supplier 理解
  7. 【clickhouse】Clickhouse 的group_concat 实现
  8. 【clickhouse】clickhouse 的 数据类型
  9. Spring Boot 中使⽤ Cache 缓存的使⽤
  10. eclipse下生成Java类图和时序图,生成UML图