10月集训test16
来源:互联网 发布:手机数据采集软件 编辑:程序博客网 时间:2024/05/19 01:10
本来应该昨天写的,结果Debug一直到今天。。。
100+20+0
第一题终于不负所望的AC了,第二题代码不够精致,本来应该可以拿50分的暴力,第三题少打了一个+1,少了40分的暴力。
上题。
1.cleaner
不是很难的题,本来代码没有自己写的那么复杂,只需要判一下是否到边界就可以了,结果我直接把边界拿出来另外算。
标准的算子矩阵和,用了容斥原理。
#include<iostream>#include<cstdlib>#include<cstdio>#include<cstring>#include<string>#include<cctype>#include<ctime>#include<cmath>#include<algorithm>#include<iomanip>using namespace std;int d,n,x,y,c,tot,ans;int a[1030][1030],b[1060900];inline int read(){ int i=0;char c; for(c=getchar();c<'0'||c>'9';c=getchar()); for(;c>='0'&&c<='9';c=getchar()) i=(i<<1)+(i<<3)+c-'0'; return i;}int main(){ //freopen("cleaner.in","r",stdin); //freopen("cleaner.out","w",stdout); d=read();n=read(); for(int i=1;i<=n;i++) { x=read(),y=read(),c=read(); a[x][y]=c; } for(int i=0;i<=1024;i++) for(int j=1;j<=1024;j++) a[i][j]+=a[i][j-1]; for(int i=1;i<=1024;i++) for(int j=0;j<=1024;j++) a[i][j]+=a[i-1][j]; for(int j=d+1;j<=1024-d;j++) b[++tot]=a[d*2][j+d]-a[d*2][j-d-1]; for(int i=d+1;i<=1024-d;i++) b[++tot]=a[i+d][d*2]-a[i-d-1][d*2]; for(int i=d+1;i<=1024-d;i++) b[++tot]=a[i+d][1024]-a[i-d-1][1024]-a[i+d][1024-d*2-1]+a[i-d-1][1024-d*2-1]; for(int j=d+1;j<=1024-d;j++) b[++tot]=a[1024][j+d]-a[1024][j-d-1]-a[1024-d*2-1][j+d]+a[1024-d*2-1][j-d-1]; b[++tot]=a[d*2][d*2];b[++tot]=a[d*2][1024]-a[d*2][1024-d*2-1]; b[++tot]=a[1024][d*2]-a[1024-d*2-1][d*2];b[++tot]=a[1024][1024]-a[1024][1024-d*2-1]-a[1024-d*2-1][1024]+a[1024-d*2-1][1024-d*2-1]; for(int i=d+1;i<=1024-d;i++) for(int j=d+1;j<=1024-d;j++) b[++tot]=a[i+d][j+d]-a[i-d-1][j+d]-a[i+d][j-d-1]+a[i-d-1][j-d-1]; sort(b+1,b+tot+1); ans=1; for(int i=tot-1;i>=1;i--) if(b[i]==b[tot]) ans++; else break; printf("%d %d",ans,b[tot]); return 0; }
2.friend
对就是这道题让我debug了很久很久很久。。。。。。
标准的最短路。
但是由于到后面边可能会有很多,加边会导致不可控的后果,所以不加边。将边权看成每走一步减1,直到0为止。dis[i][j][k]表示在(i,j)这个点且还有k的能量所花的最小费用。
#include<iostream>#include<cstdlib>#include<cstdio>#include<cstring>#include<string>#include<ctime>#include<cmath>#include<algorithm>#include<cctype>#include<iomanip>#include<queue>#include<vector>#define ll long longusing namespace std;inline int read(){ int i=0,f=1;char c; for(c=getchar();(c<'0'||c>'9')&&c!='-';c=getchar()); if(c=='-') f=-1,c=getchar(); for(;c>='0'&&c<='9';c=getchar()) i=(i<<3)+(i<<1)+c-'0'; return i*f;}const int N=205;const int fx[5]={0,-1,0,1,0};const int fy[5]={1,0,-1,0,0};const ll INF=0x3f3f3f3f3f3f3f3f;int n,m,H,X[4],Y[4];int a[N][N],b[N][N];ll dis[N][N][N<<1],D[4][4];struct node{ int d,x,y,h; friend inline bool operator >(const node &a,const node &b) { return a.d>b.d; }};priority_queue<node,vector<node>,greater<node> >q;inline void zql(int S,int T1,int T2){ int x,y,d,h; bool bz1=false,bz2=false; for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) for(int k=0;k<=H;k++) dis[i][j][k]=INF; while(!q.empty()) q.pop(); x=X[S],y=Y[S]; dis[x][y][a[x][y]]=b[x][y]; q.push((node){b[x][y],x,y,a[x][y]}); while(!q.empty()) { x=q.top().x,y=q.top().y,d=q.top().d,h=q.top().h; q.pop(); if(x==X[T1]&&y==Y[T1]&&!h) D[S][T1]=d,bz1=true; if(x==X[T2]&&y==Y[T2]&&!h) D[S][T2]=d,bz2=true; if(bz1&&bz2) return; if(h>0) { for(int i=0;i<5;i++) { int dx=x+fx[i],dy=y+fy[i]; if(dx<1||dx>n||dy<1||dy>m) continue; if(dis[dx][dy][h-1]>d) { dis[dx][dy][h-1]=d; q.push((node){d,dx,dy,h-1}); } } } else { h=a[x][y]; if(dis[x][y][h]>d+b[x][y]) { dis[x][y][h]=d+b[x][y]; q.push((node){dis[x][y][h],x,y,h}); } } }}int main(){ n=read(),m=read(); H=n+m-2; for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) a[i][j]=min(read(),H); for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) b[i][j]=read(); X[1]=read(),Y[1]=read(); X[2]=read(),Y[2]=read(); X[3]=read(),Y[3]=read(); for(int i=1;i<=3;i++) for(int j=1;j<=3;j++) D[i][j]=INF; zql(1,2,3); zql(2,1,3); zql(3,1,2); ll ans=INF;char p; if(D[2][1]+D[3][1]<ans)ans=D[2][1]+D[3][1],p='X'; if(D[1][2]+D[3][2]<ans)ans=D[1][2]+D[3][2],p='Y'; if(D[1][3]+D[2][3]<ans)ans=D[1][3]+D[2][3],p='Z'; if(ans==INF) cout<<"NO"; else cout<<p<<endl<<ans; return 0;}
3.ribbon
没有认真看样例说明啊,不是自己想的那样。
e.g.
覆盖0~5:本以为 |0|1|2|3|4|5|实际 0 1 2 3 4 5 | | | | | |
所以暴力直接打挂了。。。。。
唔正解的话,并查集是一个好选择,从最后一次涂色开始,若后面涂色时该区域已被覆盖,就与该区域连到一起,用并查集维护。
#include<iostream>#include<cstdlib>#include<cstdio>#include<cstring>#include<string>#include<ctime>#include<cmath>#include<algorithm>#include<cctype>#include<iomanip>using namespace std;struct node{ int l,r;}c[4000010];int n,ans,rr;int x[4000010],r[4000010];bool a[4000010],flag[4000010];inline int read(){ int i=0,f=1;char c; for(c=getchar();(c<'0'||c>'9')&&c!='-';c=getchar()) ; if(c=='-') f=-1,c=getchar(); for(;c>='0'&&c<='9';c=getchar()) i=(i<<1)+(i<<3)+c-'0'; return i*f;}inline int zql(int x){ if(!a[x]||x==r[x]) return x; r[x]=zql(r[x]); return r[x];}int main(){ //freopen("ribbon.in","r",stdin); //freopen("ribbon.out","w",stdout); n=read(); for(int i=1;i<=n;i++) { c[n-i+1].l=read()+1;c[n-i+1].r=read(); x[i*2-1]=c[n-i+1].l;x[i*2]=c[n-i+1].r; } int tot=n*2; for(int i=1;i<=n;i++) x[++tot]=c[i].r+1; sort(x+1,x+tot+1); tot=unique(x+1,x+tot+1)-x; for(int i=1;i<=n;i++) { c[i].l=lower_bound(x+1,x+tot+1,c[i].l)-x; c[i].r=lower_bound(x+1,x+tot+1,c[i].r)-x; rr=max(rr,c[i].r); } for(int i=1;i<=rr;i++) r[i]=i+1; for(int i=1;i<=n;i++) for(int j=c[i].l;j<=c[i].r;j++) if(!a[j]) { a[j]=true; r[j-1]=j+1; if(!flag[i]) flag[i]=true,ans++; } else { r[j]=zql(r[j]); j=r[j]; j--; } cout<<ans<<endl; return 0;}
以上。
来自2017.10.31.(Halloween)
——我认为return 0,是一个时代的终结。
阅读全文
0 0
- 10月集训test16
- test16
- test16
- 10月集训test3
- 10月集训test4
- 10月集训test5
- 10月集训test6
- 10月集训test7
- 10月集训test8
- 10月集训test9
- 10月集训test10
- 10月集训test11
- 10月集训test12
- 10月集训test13
- 10月集训test14
- 10月集训test15
- 10月集训test20
- 10月集训test19
- android的m、mm、mmm编译命令的使用
- Google 面试题:最优交易次数
- 接口与内部类
- PHP命名空间解惑
- 从Tensorflow代码中理解LSTM网络
- 10月集训test16
- opencv学习调整图像对比度
- Java8 Function和BiFunction
- Linux下Hadoop2.7.1集群环境的搭建(超详细版)
- scrapy 抓取内涵社区
- AC自动机+有向拓扑判环 Taboo Kattis
- AsyncTask的基础使用
- 机器学习实现双十一购物清单的自动商品标签归类
- Math对象总结(向上取整、向下取整、四舍五入、取随机数,取最大值、取最小值....)