。。只会AB签到
A:
就是说对于每个字符为J的位置,如果他同一列下方有I,同一行右边有O,答案就加1
那么直接对每行维护字符O的后缀和,对每列维护I的后缀和 遍历字符集,为J的时候就是两个相乘即可。
#include<bits/stdc++.h> using namespace std; typedef long long ll; const int maxn=3e3+5; int n,m; char a[maxn][maxn]; ll so[maxn][maxn],si[maxn][maxn]; int main(){ ios::sync_with_stdio(0); cin>>n>>m; for(int i=1;i<=n;i++) cin>>a[i]+1; for(int i=1;i<=n;i++){ for(int j=m;j;j--){ so[i][j]+=so[i][j+1]; if(a[i][j]=='O') so[i][j]++; } } for(int i=1;i<=m;i++){ for(int j=n;j;j--){ si[j][i]+=si[j+1][i]; if(a[j][i]=='I') si[j][i]++; } } ll ans=0; for(int i=1;i<=n;i++){ for(int j=1;j<=m;j++){ if(a[i][j]=='J'){ ans+=so[i][j]*si[i][j]; } } } cout<<ans; return 0; }
B
对于画,以美观度为第一关键词降序,美观度一样以大小降序。
对于画框从大到小排序
倒着遍历,如果当前画框大小≥画的大小,则个数加1.
为什么不能正序来呢 如果正序的话,当画框大小不足以装下这幅画,就有个问题了,画主要是按照美观度排序的,可能这个装不下,在后面可能会有更小的画,考虑的较多,比较麻烦。倒序遍历则不需要有这个顾虑,装得下就装,装不下,画就往后移动,因为画框现在的这个就是目前没选择的最大了,不可能去移动画框,只能移动画来判断。
#include<bits/stdc++.h> using namespace std; const int maxn=1e5+50; struct node { int big,v; bool friend operator<(node a,node b){ if(a.v==b.v) return a.big>b.big; return a.v>b.v; } }a[maxn]; int b[maxn]; int main(){ int n,m; scanf("%d%d",&n,&m); for(int i=1;i<=n;i++) scanf("%d%d",&a[i].big,&a[i].v); for(int i=1;i<=m;i++) scanf("%d",&b[i]); sort(a+1,a+1+n); sort(b+1,b+1+m,[](int x,int y){ return x>y; }); int cnt=0; for(int i=1,j=1;i<=n&&j<=m;i++){ if(b[j]>=a[i].big) cnt++,j++; } printf("%d",cnt); return 0; }