标签:+= inf scanf gcc span 一句话 info 二维 name
似乎是打表+暴力专场,可惜我什么规律也找不出来,一题模拟乱搞,二三题神仙打表。
T1懒得写题面了 一句话题意,就是问你在一个n*m的01矩阵中有多少个k*k的子矩阵包含1
正解二维前缀和,考试的时候我想的是暴力模拟,把所有子矩阵扫一遍,打标记就得了。暴力模拟也挺好做,虽然自己造的大数据炸掉了,但是交上去手动开O2+读优就可以艹过去。复杂度O(n*m)对于这道题足够了。
代码:
#pragma GCC optimize(2) #include<bits/stdc++.h> using namespace std; const int N=1550; inline void read(int &re) { char ch; while((ch=getchar())<‘0‘||ch>‘1‘); re=ch-48; } int n,m,k; int jz; int sx,sy,ex,ey; long long tot; long long spe; int x[N],y[N]; int cnt; int flag1[N][N]; int flag2[N][N]; int main(){ freopen("a.in","r",stdin); freopen("a.out","w",stdout); scanf("%d%d%d",&n,&m,&k); for(register int i=1;i<=n;i++){ for(register int j=1;j<=m;j++){ read(jz);//一定要读优 if(jz==1){ spe++; x[++cnt]=j; y[cnt]=i; } } } if(k==1){//等于1直接输出 printf("%lld\n",spe); return 0; } sx=1,sy=1,ex=k,ey=k; while(ex<=m&&ey<=n){ for(register int i=1;i<=cnt;i++){ if(x[i]>=sx&&y[i]>=sy&&x[i]<=ex&&y[i]<=ey&&((!flag1[sx][sy])||(!flag2[ex][ey]))){//在范围内 tot++; if(!flag1[sx][sy]) flag1[sx][sy]=1;//打标记 if(!flag2[ex][ey]) flag2[ex][ey]=1; } } sx+=1; ex+=1; if(sx>m-k+1){//扫下一行 sx=1; ex=k; sy+=1; ey+=1; } } printf("%lld\n",tot); return 0; }
不敢保证是完全正确的,给出std:
#include <bits/stdc++.h> using namespace std; const int N = 1033; char s[N][N]; int n, m, k, a[N][N]; int main() { //freopen("a.in","r",stdin); //freopen("a.out","w",stdout); scanf("%d%d%d", &n, &m, &k); for (int i = 1; i <= n; i++) { scanf("%s", s[i] + 1); } int all = (n + 1 - k) * (m + 1 - k); for (int i = 1; i <= n; i++) { for (int j = 1; j <= m; j++) { if (s[i][j] == ‘1‘) { a[i][j] = 0; } else { a[i][j] = min(a[i - 1][j - 1], min(a[i - 1][j], a[i][j - 1])) + 1; } if (a[i][j] >= k) { all--; } } } printf("%d\n", all); }
T2 就是问你1-n中约数的约数个数和最大的数是谁 打表可做,不过n的范围过大。而且我巨臭的打表只能打前两个点。题解如下:
std:
#include <bits/stdc++.h> using namespace std; typedef long long ll; int pri[] = {2,3,5,7,11,13,17,19,23,29,31,37,41,43,47,53}; ll n, coef, cur, ans, ans2; void dfs(int p, ll cur, ll coef, int last) { assert(cur > 0 && coef > 0); if (coef > ans) { ans = coef; ans2 = cur; } else if (coef == ans) { ans2 = min(ans2, cur); } for (int i = 1; i <= last && cur <= n / pri[p] && cur * pri[p] <= n; i++) { cur *= pri[p]; dfs(p + 1, cur, coef * ((i + 2) * (i + 1) / 2), i); } } int main() { freopen("b.in","r",stdin); freopen("b.out","w",stdout); scanf("%lld", &n); dfs(0, 1, 1, 999); printf("%lld\n%lld\n", ans2, ans); }
T3 先给出递推式,不过面对如此大的数据范围递推也没办法,正解是真的神仙,几个位运算判断一波就搞了,%%%%%
std:
#include <bits/stdc++.h> using namespace std; int n; long long f0, f1; int main() { freopen("c.in","r",stdin); freopen("c.out","w",stdout); scanf("%d", &n); int tg = 0; for (int i = 30; ~i; i--) { if (tg) { if ((n >> i) & 1) { f0 = f0 * 3 + f1 * 2 + 1; } else { f0 = f0 * 3 + 1; f1 = f1 * 2; } } else if ((n >> i) & 1) { tg = 1; f1++; } } printf("%lld\n", (f0 + f1) * 2 + 1); }
%%%%% deco&sxk dalao 300pts AK
标签:+= inf scanf gcc span 一句话 info 二维 name
原文地址:https://www.cnblogs.com/LJB666/p/11266547.html