前面的碎碎念:
菜鸡不敢打这个比赛,赛后看题解有“水题”就补了题。
戳我传送
A、勇者比武
大意:
H * W的格子上放了J,O,I三种字符,求满足条件(i,j,k,l)的四元组的数量,(i,j)上是J,(i,l)上是O,(k,j)上是I。其中l大于j,k大于i,也就是说问有多少JOI的组合满足O在J的右边,I在J的下边。
思路:
前缀和变形一下,从行末和列末往前计算当前位置右边出现了多少O下面出现了多少I,这个位置如果出现了J,那么这个J的贡献就是两个集合的组合数,将全部J的贡献求和就是结果了,复杂度 (m*n)。
Code;
#include<bits/stdc++.h> using namespace std; const int maxn=3005; int read(){ int x=0;char ch=getchar(); while(!isdigit(ch)) ch=getchar(); while(isdigit(ch)) x=(x<<3)+(x<<1)+(ch^48),ch=getchar(); return x; } char a[maxn][maxn]; long long u[maxn][maxn],v[maxn][maxn]; int main() { int h=read(),w=read(); for(int i=1;i<=h;++i) scanf("%s",a[i]+1); for(int i=1;i<=h;++i) for(int j=w;j;--j) { u[i][j]+=u[i][j+1]; if(a[i][j]=='O') ++u[i][j]; } for(int j=1;j<=w;++j) for(int i=h;i;--i) { v[i][j]+=v[i+1][j]; if(a[i][j]=='I') ++v[i][j]; } long long ans=0; for(int i=1;i<=h;++i) for(int j=1;j<=w;++j) if(a[i][j]=='J') ans+=u[i][j]*v[i][j]; cout<<ans<<endl; }
B、画展:
题目大意:
考虑到美观,右边的画框不小于左边的,右边的画不能没左边的好看。
思路:
我们可以用贪心的策略。其实左边和右边不重要,选好后左右颠倒就可以了,题目就变为:左边的框大于等于右边的,左边的框不能没有右边好看。先选择装好看的,如果都好看,就先装体积大的,接下来就可以贪心的用最大的框去装剩下的画中最好看的,如果装不下就换过一副画。复杂度 (NlogN+MlogM).
可以试着先装美观最小的,如果美观一样先装最小的,然后贪心的用最小的框框去装剩下的框中美观最小的,装不下就换一个框,但是这样很有可能会浪费几个框,比如后面可能有更好看的画还更小,且能装下这个画框,从而后面的结果也可能会比不要这个框的结果要大。如果倒叙遇到当前美度的画放不下当前的画框,我们试着不要这副画,如果要这幅画而是不要这个框会不会更有更优的结果(肯定没有!这个框都要不起后面就没有要得起的了,把前面已经装了画的画框拆下来装这个的结果显然是一样的,这就是拆东墙补西墙,随便前i幅画和前j个框怎么配对,只要符合条件,对后面是没有影响的)。所以我们选择倒序去贪心。
Code:
#include<bits/stdc++.h> using namespace std; int read(){ int x=0;char ch=getchar(); while(!isdigit(ch)) ch=getchar(); while(isdigit(ch)) x=(x<<3)+(x<<1)+(ch^48),ch=getchar(); return x; } void print(int x){ if(x>=10) print(x/10); putchar(x%10+'0'); } const int maxn=1e5+5; struct node{ int v,val; bool operator<(const node&a) const { if(val==a.val) return v>a.v; return val>a.val; } }a[maxn]; int b[maxn]; int main() { int n=read(),m=read(); for(int i=1;i<=n;++i) a[i].v=read(),a[i].val=read(); for(int i=1;i<=m;++i) b[i]=read(); sort(a+1,a+1+n); sort(b+1,b+1+m,[](int a,int b){ return a>b; }); int cnt=0; for(int i=1,j=1;i<=n&&j<=m;++i) if(b[j]>=a[i].v) { ++cnt,++j; } print(cnt),puts(""); }