解题报告
JZOJ 3831 地图的密度(水题)
代码
#include <cstdio>
#include <cctype>
#define rr register
#define min(a,b) ((a)<(b)?(a):(b))
#define max(a,b) ((a)>(b)?(a):(b))
using namespace std;
int n,m,a[261][261];
inline signed iut(){
rr int ans=0; rr char c=getchar();
while (!isdigit(c)) c=getchar();
while (isdigit(c)) ans=(ans<<3)+(ans<<1)+(c^48),c=getchar();
return ans;
}
inline void print(int ans){
if (ans>9) print(ans/10);
putchar(ans%10+48);
}
signed main(){
freopen("map.in","r",stdin);
freopen("map.out","w",stdout);
n=iut(); m=iut();
for (rr int i=1;i<=n;++i)
for (rr int j=1;j<=n;++j)
a[i][j]=a[i-1][j]+a[i][j-1]-a[i-1][j-1]+iut();
for (rr int i=1;i<=n;++i)
for (rr int j=1;j<=n;++j){
rr int lx=max(i-m,1),ly=max(j-m,1),rx=min(i+m,n),ry=min(j+m,n);
print(a[rx][ry]-a[lx-1][ry]-a[rx][ly-1]+a[lx-1][ly-1]),putchar(j==n?10:32);
}
return 0;
}
JZOJ 3832 在哪里建酿酒厂(水题)
代码(O(n^2)卡常AC)
#include <cstdio>
#include <cctype>
#define rr register
#define min(a,b) ((a)>(b)?(b):(a))
using namespace std;
const int N=20011; typedef long long ll;
int n,a[N],dis[N]; ll pre[N],suf[N];
inline signed iut(){
rr int ans=0; rr char c=getchar();
while (!isdigit(c)) c=getchar();
while (isdigit(c)) ans=(ans<<3)+(ans<<1)+(c^48),c=getchar();
return ans;
}
signed main(){
freopen("bro.in","r",stdin);
freopen("bro.out","w",stdout);
n=iut(); rr ll ans=1e16;
for (rr int i=1;i<=n;++i) a[i]=a[i+n]=iut(),dis[i]=dis[i+n]=iut();
for (rr int i=2;i<=n*2;++i) a[i]+=a[i-1];
for (rr int i=1;i<=n;++i){
rr int l=i,r=i+n-1; pre[l]=suf[r]=0; rr ll now=1e16;
for (rr int j=l+1;j<=r;++j) pre[j]=pre[j-1]+1ll*(a[j-1]-a[l-1])*dis[j-1];
for (rr int j=r-1;j>=l;--j) suf[j]=suf[j+1]+1ll*(a[r]-a[j])*dis[j];
for (rr int j=l;j<=r;++j) now=min(now,pre[j]+suf[j]); ans=min(ans,now);
}
return !printf("%lld",ans);
}
想看正解看看这个(https://blog.csdn.net/Mr_wuyongcong/article/details/102915841)
JZOJ 1956 洛谷 2449 矩形
题目
问多个矩形组成的图形中有多少个连通块
分析
分类讨论,即可(我原来洛谷AC代码结果WA掉了QAQ)
代码
#include <cstdio>
#include <cctype>
#define rr register
using namespace std;
struct rec{int lx,ly,rx,ry;}a[7011];
int n,f[7011],ans,cnt[7011];
inline signed iut(){
rr int ans=0; rr char c=getchar();
while (!isdigit(c)) c=getchar();
while (isdigit(c)) ans=(ans<<3)+(ans<<1)+(c^48),c=getchar();
return ans;
}
inline signed getf(int u){return f[u]==u?u:f[u]=getf(f[u]);}
signed main(){
freopen("pro.in","r",stdin);
freopen("pro.out","w",stdout);
n=iut();
for (rr int i=1;i<=n;++i) f[i]=i;
for (rr int i=1;i<=n;++i){
a[i]=(rec){iut(),iut(),iut(),iut()};
for (rr int j=1;j<i;++j){
rr rec x=a[i],y=a[j],t; rr bool flag=0;
if (x.lx>y.lx||(x.lx==y.lx&&x.ly>y.ly)) t=x,x=y,y=t;
if (x.ly<=y.ly&&(y.lx<=x.rx&&y.ly<=x.ry)&&(x.rx!=y.lx||x.ry!=y.ly)) flag=1;
if (x.ly>y.ly&&(y.lx<=x.rx&&y.ry>=x.ly)&&(x.rx!=y.lx||x.ly!=y.ry)) flag=1;
if (flag){
rr int fa=getf(i),fb=getf(j);
rr int fc=fa<fb?fa:fb;
if (fa!=fb) f[fc]=fa^fb^fc;
}
}
}
for (rr int i=1;i<=n;++i) ans+=f[i]==i;
return !printf("%d",ans);
}
JZOJ 3833 平坦的折线
题目
现在我们在一张纸上有一个笛卡尔坐标系。我们考虑在这张纸上用铅笔从左到右画的折线。我们要求任何两个点之间连接的直线段与 x x x轴的夹角在 − 45 ∼ 45 -45\sim 45 −45∼45之间,一条满足以上条件的折线称之为平坦的折线。假定给出了 n n n个不同的整点(坐标为整数的点),最少用几条平坦的折线可以覆盖所有的点?
分析
考虑把它转换,首先把坐标系逆时针旋转45度,也就是
x
′
=
x
∗
cos
θ
+
y
∗
sin
θ
,
y
′
=
y
∗
cos
θ
−
x
∗
sin
θ
x'=x*\cos\theta+y*\sin\theta,y'=y*\cos\theta-x*\sin\theta
x′=x∗cosθ+y∗sinθ,y′=y∗cosθ−x∗sinθ
然后按照第一关键字为横坐标从小到大排列,第二关键字为纵坐标从大到小排列,按照纵坐标求最长不下降子序列长度即可
代码
#include <cstdio>
#include <cctype>
#include <algorithm>
#define rr register
using namespace std;
const int N=30011;
struct rec{int x,y;}a[N]; int n,b[N],len;
inline signed iut(){
rr int ans=0; rr char c=getchar();
while (!isdigit(c)) c=getchar();
while (isdigit(c)) ans=(ans<<3)+(ans<<1)+(c^48),c=getchar();
return ans;
}
bool cmp(const rec &a,const rec &b){return a.x<b.x||(a.x==b.x&&a.y>b.y);}
signed main(){
freopen("lam.in","r",stdin);
freopen("lam.out","w",stdout);
n=iut();
for (rr int i=1;i<=n;++i){
rr int x=iut(),y=iut();
a[i]=(rec){x+y,y-x};
}
sort(a+1,a+1+n,cmp);
b[++len]=a[1].y;
for (rr int i=2;i<=n;++i){
if (a[i].y>b[len]) b[++len]=a[i].y;
else b[lower_bound(b+1,b+1+len,a[i].y)-b]=a[i].y;
}
return !printf("%d",len);
}