今天(准确说是昨天,一下子就过12点了)下午刚参加了CSP认证考试,大概是考了220(前两题AC,第三题太折磨了懒得看了,后面两题各混了10分),唯一有点参与感的就是B题了,于是这里分析下我的B题思路。
题意:对于
n
?
n
n*n
n?n的矩阵,求存在多少个这样的点(以该点为中心半径为
r
r
r 正方形块中的总值的平均数不大于阈值
t
t
t )
思路:如上图所示,靠边缘的点所形成的方块是不完整的,当时第一遍我是打算用dp计算中央部分完整的块,而对于边缘不完整的块则采用暴力,实现起来比较简单,没想到的是有30%(
n
<
=
600
,
r
<
=
100
n<=600,r<=100
n<=600,r<=100)TLE了,码代码前只是粗略的计算了一下时间复杂度,感觉能过。于是又想到了下面的方法,消除了暴力的部分。
人为地将矩阵向外扩充
r
r
r 个单位,这样就避免了靠近边缘的点形成不完整的方块,并且对于扩充的格子均填上阈值
t
t
t ,这样在计算平均值时又保持了原方块的平均值与阈值的大小关系
s u m m ≤ t → s u m ≤ m ? t s u m + ( n ? t ) ≤ m ? t + ( n ? t ) s u m + ( n ? t ) ≤ ( m + n ) ? t s u m + n ? t m + n ≤ t \frac{sum}{m} \le t \to sum \le m*t \\ sum+(n*t) \le m*t+(n*t) \\ sum+(n*t) \le (m+n)*t \\ \frac{sum+n*t}{m+n} \le t msum?≤t→sum≤m?tsum+(n?t)≤m?t+(n?t)sum+(n?t)≤(m+n)?tm+nsum+n?t?≤t
dp的部分有空再分析分析,现在得睡觉了。。
代码:(赛后重写了一遍,没交过,不保证AC)
#include<bits/stdc++.h>
#define debug1(x) cout<<#x<<":"<<x<<endl
typedef long long ll;
typedef unsigned long long ull;
const int N = 1000;
using namespace std;
int a[N][N], dp[N][N],row[N],col[N][N];
int n,L,r,t,R;
void init()
{
for(int i = 0; i < N; i++)
{
row[i] = -1;
for(int j = 0; j < N; j++)
{
a[i][j] = t;
col[i][j] = -1;
}
}
}
int calc_row(int i)
{
if(row[i] == -1)
{
int sum = 0;
for(int j = 0 - r; j <= 0 + r; j++) sum += a[i][R + j];
row[i] = sum;
}
return row[i];
}
int calc_col(int i, int j)
{
if(col[i - 1][j] == -1)
{
int sum = 0;
for(int k = i - r; k <= i + r; k++) sum += a[k][j];
col[i][j] = sum;
}
else
{
col[i][j] = col[i - 1][j] + a[i + r][j] - a[i - 1 - r][j];
}
return col[i][j];
}
int main()
{
cin>>n>>L>>r>>t;
R = r + 5;
init();
for(int i = 0; i < n; i++)
{
for(int j = 0; j < n; j++)
{
scanf("%d",&a[R + i][R + j]);
}
}
// calculate dp[0][0]
for(int i = 0 - r; i <= 0 + r; i++)
{
for(int j = 0 - r; j <= 0 + r; j++)
{
dp[0][0] += a[R + i][R + j];
}
}
for(int i = 0; i < n; i++)
{
if(i)
{
int sub_row = calc_row(R + i - 1 - r);
int add_row = calc_row(R + i + r);
dp[i][0] = dp[i - 1][0] + add_row - sub_row;
}
for(int j = 1; j < n; j++)
{
int sub_col = calc_col(R + i, R + j - 1 - r);
int add_col = calc_col(R + i, R + j + r);
dp[i][j] = dp[i][j - 1] + add_col - sub_col;
}
}
int ans = 0, block = (2 * r + 1)*(2 * r + 1);
for(int i = 0; i < n; i++)
{
for(int j = 0; j < n; j++)
{
if(dp[i][j] <= t * block) ans++;
}
}
cout<<ans<<"\n";
return 0;
}
刚去学习了一下二维前缀和的知识,果然比自己写的dp简约多了!
代码:采用二维前缀和+人为扩矩(依旧不保证正确,目前还没机会交)
#include<bits/stdc++.h>
#define debug1(x) cout<<#x<<":"<<x<<endl
typedef long long ll;
typedef unsigned long long ull;
const int N = 1000;
using namespace std;
int a[N][N], dp[N][N], s[N][N];
int n,L,r,t,R;
void init()
{
for(int i = 0; i < N; i++)
{
for(int j = 0; j < N; j++)
{
a[i][j] = t;
}
}
}
int main()
{
cin>>n>>L>>r>>t;
R = r + 5;
init();
for(int i = 0; i < n; i++)
{
for(int j = 0; j < n; j++)
{
scanf("%d",&a[R + i][R + j]);
}
}
for(int i = 0 - r; i < n + r; i++)
{
for(int j = 0 - r; j < n + r; j++)
{
s[R + i][R + j] = s[R + i - 1][R + j]
+ s[R + i][R + j - 1]
- s[R + i - 1][R + j - 1]
+ a[R + i][R + j];
}
}
int i1,j1,i2,j2,sum;
int ans = 0, block = (2 * r + 1)*(2 * r + 1);
for(int i = 0; i < n; i++)
{
for(int j = 0; j < n; j++)
{
i1 = R + i - r; i2 = R + i + r;
j1 = R + j - r; j2 = R + j + r;
sum = s[i2][j2]
- s[i2][j1 - 1]
- s[i1 - 1][j2]
+ s[i1 - 1][j1 - 1];
if(sum <= t * block) ans++;
}
}
cout<<ans<<"\n";
return 0;
}
A题:比较基础的统计题,按题目要求统计每个数出现的次数即可
#include<bits/stdc++.h>
#define debug1(x) cout<<#x<<":"<<x<<endl
typedef long long ll;
typedef unsigned long long ull;
using namespace std;
int main()
{
int n, m, L;
cin>>n>>m>>L;
vector<int> ans(L);
int tmp;
for(int i = 0; i < n; i++)
{
for(int j = 0; j < m; j++)
{
scanf("%d",&tmp);
ans[tmp]++;
}
}
for(int i = 0; i < L; i++) cout<<ans[i]<<" ";
return 0;
}
错误描述: 在开发.net项目中,通过microsoft.ACE.oledb读取excel文件信息时,报...
上篇文章给大家介绍了 Java正则表达式匹配,替换,查找,切割的方法 ,接下来,...
复制代码 代码如下: % URL="http://news.163.com/special/00011K6L/rss_newstop....
DELETEFROMTablesWHEREIDNOTIN(SELECTMin(ID)FROMTablesGROUPBYName) Min的话保...
本文实例讲述了Laravel框架源码解析之反射的使用。分享给大家供大家参考,具体如...
工具:Eclipse,Oracle,smartupload.jar;语言:jsp,Java;数据存储:Oracle。...
4月11日20:30~22:00通过腾讯会议进行了第二次在线学习讨论我把学习笔记整理一下...
正则忽略大小写 – RegexOptions.IgnoreCase 例如: 复制代码 代码如下: Str = R...
项目中用到的一些特殊字符和图标 html代码 XML/HTML Code 复制内容到剪贴板 div ...
Elasticsearch 是通过 Lucene 的倒排索引技术实现比关系型数据库更快的过滤。特...