[NOIP2017模拟]裁剪表格
来源:互联网 发布:淘宝买家怎么快速升钻 编辑:程序博客网 时间:2024/05/25 23:57
2017.10.20 T3 1999
样例数据
输入
4 4 2
1 1 2 2
1 1 2 2
3 3 4 4
3 3 4 4
1 1 3 3 2 2
3 1 1 3 2 2
输出
4 4 3 3
4 4 3 3
2 2 1 1
2 2 1 1
分析:如果说把点暴力更换的话,是O(
真是和时间赛跑的真男人,绝不超过4s!
之前的考试已经做过两道链表题了,这道的正解竟然也是链表(其实看看这复杂的转换也猜得到,果然wuvin对链表情有独钟),但是,升格为多向链表(记录上下左右的点的坐标,由于输出只需要向下的链和向右的链,所以也可以优化成只记录右和下的坐标),我是把map[0][1]作为基准点,每次的ri、ci就是基准点向下跳ri次再向右跳ci-1次就找到了需要修改的两个子矩阵的左上角那个点,然后就走一圈,把多向链表改接(实现极为复杂!!!我调了一个半小时,多谢Anonymous_jacklovecj的帮助,祝rp++),复杂度降为O(
代码
100%暴力+register(很爽有没有?完全无脑!)
#include<iostream>#include<cstdio>#include<cstdlib>#include<cstring>#include<string>#include<ctime>#include<cmath>#include<algorithm>#include<cctype>#include<iomanip>#include<queue>#include<set>using namespace std;int getint(){ int sum=0,f=1; char ch; for(ch=getchar();!isdigit(ch)&&ch!='-';ch=getchar()); if(ch=='-') { f=-1; ch=getchar(); } for(;isdigit(ch);ch=getchar()) sum=(sum<<3)+(sum<<1)+ch-48; return sum*f;}int n,m,q,r1,c1,r2,c2,h,w;int map[1010][1010];int main(){ freopen("table.in","r",stdin); freopen("table.out","w",stdout); n=getint(),m=getint(),q=getint(); for(register int i=1;i<=n;++i) for(register int j=1;j<=m;++j) map[i][j]=getint(); while(q--) { r1=getint(),c1=getint(),r2=getint(),c2=getint(),h=getint(),w=getint(); register int dx=r2-r1,dy=c2-c1; for(register int i=r1;i<r1+h;++i) for(register int j=c1;j<c1+w;++j) swap(map[i][j],map[i+dx][j+dy]); } for(register int i=1;i<=n;++i) { for(register int j=1;j<m;++j) cout<<map[i][j]<<" "; cout<<map[i][m]<<'\n'; } return 0;}
100%链表正解(可以说,每一个有注释的地方,我都付出了沉痛的时间代价)
#include<iostream>#include<cstdio>#include<cstdlib>#include<cstring>#include<string>#include<ctime>#include<cmath>#include<algorithm>#include<cctype>#include<iomanip>#include<queue>#include<set>using namespace std;int getint(){ int sum=0,f=1; char ch; for(ch=getchar();!isdigit(ch)&&ch!='-';ch=getchar()); if(ch=='-') { f=-1; ch=getchar(); } for(;isdigit(ch);ch=getchar()) sum=(sum<<3)+(sum<<1)+ch-48; return sum*f;}struct node{ int w; int l[2],r[2],u[2],d[2];}map[1010][1010];int n,m,q,r1,c1,r2,c2,h,w;int main(){ freopen("table.in","r",stdin); freopen("table.out","w",stdout); n=getint(),m=getint(),q=getint(); for(int i=1;i<=n;++i) for(int j=1;j<=m;++j) map[i][j].w=getint(); for(int i=0;i<=n+1;++i)//在图外的一圈也要附上链表,之后转接才不会错 for(int j=0;j<=m+1;++j)//记录所有上下左右的横坐标、纵坐标...... { map[i][j].r[0]=i,map[i][j].r[1]=j+1; map[i][j].l[0]=i,map[i][j].l[1]=j-1; map[i][j].u[0]=i-1,map[i][j].u[1]=j; map[i][j].d[0]=i+1,map[i][j].d[1]=j; } while(q--) { r1=getint(),c1=getint(),r2=getint(),c2=getint(),h=getint(),w=getint(); int dian1x=0,dian1y=1,dian2x=0,dian2y=1,newx,newy; for(int i=1;i<=r1;++i)//第一个矩阵先向下跳 { newx=map[dian1x][dian1y].d[0]; newy=map[dian1x][dian1y].d[1]; dian1x=newx,dian1y=newy; } for(int i=1;i<c1;++i)//第一个矩阵再向右跳找到了左上角的点 { newx=map[dian1x][dian1y].r[0]; newy=map[dian1x][dian1y].r[1]; dian1x=newx,dian1y=newy; } for(int i=1;i<=r2;++i)//第二个矩阵同理 { newx=map[dian2x][dian2y].d[0]; newy=map[dian2x][dian2y].d[1]; dian2x=newx,dian2y=newy; } for(int i=1;i<c2;++i) { newx=map[dian2x][dian2y].r[0]; newy=map[dian2x][dian2y].r[1]; dian2x=newx,dian2y=newy; }//绕着两个矩阵走一圈,把它们的最外面的一圈点相互转接 for(int i=1;i<=w;++i)//向右走长(后面代码块同理) { swap(map[dian1x][dian1y].u,map[dian2x][dian2y].u);//它们互换了位置,所以它们上面的点变成了对方的 map[map[dian1x][dian1y].u[0]][map[dian1x][dian1y].u[1]].d[0]=dian1x;//这几行就是把它们上面的点指向的下面的点改成互换后的点 map[map[dian1x][dian1y].u[0]][map[dian1x][dian1y].u[1]].d[1]=dian1y; map[map[dian2x][dian2y].u[0]][map[dian2x][dian2y].u[1]].d[0]=dian2x; map[map[dian2x][dian2y].u[0]][map[dian2x][dian2y].u[1]].d[1]=dian2y;//这里是在长上向右移动 if(i!=w)//只向右移w-1次就到边边上了,不能移出界了 { newx=map[dian1x][dian1y].r[0]; newy=map[dian1x][dian1y].r[1]; dian1x=newx,dian1y=newy; newx=map[dian2x][dian2y].r[0]; newy=map[dian2x][dian2y].r[1]; dian2x=newx,dian2y=newy; } } for(int i=1;i<=h;++i)//向下走宽 { swap(map[dian1x][dian1y].r,map[dian2x][dian2y].r); map[map[dian1x][dian1y].r[0]][map[dian1x][dian1y].r[1]].l[0]=dian1x; map[map[dian1x][dian1y].r[0]][map[dian1x][dian1y].r[1]].l[1]=dian1y; map[map[dian2x][dian2y].r[0]][map[dian2x][dian2y].r[1]].l[0]=dian2x; map[map[dian2x][dian2y].r[0]][map[dian2x][dian2y].r[1]].l[1]=dian2y; if(i!=h) { newx=map[dian1x][dian1y].d[0]; newy=map[dian1x][dian1y].d[1]; dian1x=newx,dian1y=newy; newx=map[dian2x][dian2y].d[0]; newy=map[dian2x][dian2y].d[1]; dian2x=newx,dian2y=newy; } } for(int i=1;i<=w;++i)//向左走长 { swap(map[dian1x][dian1y].d,map[dian2x][dian2y].d); map[map[dian1x][dian1y].d[0]][map[dian1x][dian1y].d[1]].u[0]=dian1x; map[map[dian1x][dian1y].d[0]][map[dian1x][dian1y].d[1]].u[1]=dian1y; map[map[dian2x][dian2y].d[0]][map[dian2x][dian2y].d[1]].u[0]=dian2x; map[map[dian2x][dian2y].d[0]][map[dian2x][dian2y].d[1]].u[1]=dian2y; if(i!=w) { newx=map[dian1x][dian1y].l[0]; newy=map[dian1x][dian1y].l[1]; dian1x=newx,dian1y=newy; newx=map[dian2x][dian2y].l[0]; newy=map[dian2x][dian2y].l[1]; dian2x=newx,dian2y=newy; } } for(int i=1;i<=h;++i)//向上走宽 { swap(map[dian1x][dian1y].l,map[dian2x][dian2y].l); map[map[dian1x][dian1y].l[0]][map[dian1x][dian1y].l[1]].r[0]=dian1x; map[map[dian1x][dian1y].l[0]][map[dian1x][dian1y].l[1]].r[1]=dian1y; map[map[dian2x][dian2y].l[0]][map[dian2x][dian2y].l[1]].r[0]=dian2x; map[map[dian2x][dian2y].l[0]][map[dian2x][dian2y].l[1]].r[1]=dian2y; if(i!=h) { newx=map[dian1x][dian1y].u[0]; newy=map[dian1x][dian1y].u[1]; dian1x=newx,dian1y=newy; newx=map[dian2x][dian2y].u[0]; newy=map[dian2x][dian2y].u[1]; dian2x=newx,dian2y=newy; } } } int dian1x=0,dian1y=1,dian2x,dian2y,newx,newy; for(int i=1;i<=n;++i) { newx=map[dian1x][dian1y].d[0];//从基准点的下面一个点(也就是最后答案图的map[1][1])开始输出 newy=map[dian1x][dian1y].d[1]; dian1x=newx,dian1y=newy; dian2x=dian1x,dian2y=dian1y; for(int j=1;j<=m;++j)//输出、向右、输出、向右...... { cout<<map[dian2x][dian2y].w<<" "; newx=map[dian2x][dian2y].r[0]; newy=map[dian2x][dian2y].r[1]; dian2x=newx,dian2y=newy; } cout<<'\n'; } return 0;}
另附,标算代码(只记录下链表和右链表)
#include<iostream>#include<cstdio>#include<cstring>#include<string>#include<algorithm>#include<cmath>#include<vector>#include<queue>#define ll long longusing namespace std;int getint(){ 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=1005;int n,m,Q,num;int f[N*N][2],lab[N][N],v[N*N];int getlab(int a,int b){ int p=lab[0][0]; for(int i=1;i<=a;i++)p=f[p][1]; for(int i=1;i<=b;i++)p=f[p][0]; return p;}int main(){ freopen("table.in","r",stdin); freopen("table.out","w",stdout); int a,b,c,d,h,w; n=getint(),m=getint(),Q=getint(); for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) v[lab[i][j]=++num]=getint(); for(int i=0;i<=m+1;i++) lab[0][i]=++num,lab[n+1][i]=++num; for(int i=1;i<=n;i++) lab[i][0]=++num,lab[i][m+1]=++num; for(int i=0;i<=n;i++) for(int j=0;j<=m;j++) { f[lab[i][j]][0]=lab[i][j+1]; f[lab[i][j]][1]=lab[i+1][j]; } while(Q--) { a=getint(),b=getint(),c=getint(),d=getint(),h=getint(),w=getint(); int p1=getlab(a-1,b-1),p2=getlab(c-1,d-1); int t1,t2,ww,hh; for(t1=p1,t2=p2,ww=1;ww<=w;ww++)swap(f[t1=f[t1][0]][1],f[t2=f[t2][0]][1]); for(hh=1;hh<=h;hh++)swap(f[t1=f[t1][1]][0],f[t2=f[t2][1]][0]); for(t1=p1,t2=p2,hh=1;hh<=h;hh++)swap(f[t1=f[t1][1]][0],f[t2=f[t2][1]][0]); for(ww=1;ww<=w;ww++)swap(f[t1=f[t1][0]][1],f[t2=f[t2][0]][1]); } for(int i=1,p=lab[0][0];i<=n;i++) { for(int j=1,t=p=f[p][1];j<=m;j++) cout<<v[t=f[t][0]]<<" "; cout<<'\n'; } return 0;}
另附,指针写法
#include<bits/stdc++.h>using namespace std;inline int read(){ char ch=getchar();int i=0,f=1; while(!isdigit(ch)){if(ch=='-')f=-1;ch=getchar();} while(isdigit(ch)){i=(i<<1)+(i<<3)+ch-'0';ch=getchar();} return i*f;}const int Maxn=1e3+50;struct node{ node *right,*down; int val;}Pool[Maxn*Maxn],*pool=Pool,*pos[Maxn][Maxn];inline node* newnode(int val){ ++pool; pool->right=pool->down=NULL; pool->val=val; return pool;}int n,m,q;inline node* findpos(int x,int y){ node *now=pos[0][0]; for(register int i=1;i<=x;i++)now=now->down; for(register int i=1;i<=y;i++)now=now->right; return now;}inline void W(int x){ static int buf[50]; if(!x){putchar('0');return;} if(x<0){putchar('-');x=-x;} while(x){buf[++buf[0]]=x%10;x/=10;} while(buf[0])putchar(buf[buf[0]--]+'0');}int main(){ n=read(),m=read(),q=read(); pos[0][0]=newnode(0); for(register int i=1;i<=m;i++){ pos[0][i]=newnode(0); pos[0][i-1]->right=pos[0][i]; } for(register int i=1;i<=n;i++){ pos[i][0]=newnode(0); pos[i-1][0]->down=pos[i][0]; for(register int j=1;j<=m;j++){ pos[i][j]=newnode(read()); pos[i-1][j]->down=pos[i][j]; pos[i][j-1]->right=pos[i][j]; } } for(register int i=1;i<=q;i++){ int dx1=read(),dy1=read(),dx2=read(),dy2=read(),h=read(),w=read(); node *lup1=findpos(dx1-1,dy1),*lup2=findpos(dx2-1,dy2); node *lup3=findpos(dx1,dy1-1),*lup4=findpos(dx2,dy2-1); node *ldown1=findpos(dx1+h-1,dy1),*ldown2=findpos(dx2+h-1,dy2); node *rup1=findpos(dx1,dy1+w-1),*rup2=findpos(dx2,dy2+w-1); for(register int j=1;j<=w;j++){ swap(lup1->down,lup2->down); lup1=lup1->right,lup2=lup2->right; } for(register int j=1;j<=h;j++){ swap(lup3->right,lup4->right); lup3=lup3->down,lup4=lup4->down; } for(register int j=1;j<=w;j++){ swap(ldown1->down,ldown2->down); ldown1=ldown1->right,ldown2=ldown2->right; } for(register int j=1;j<=h;j++){ swap(rup1->right,rup2->right); rup1=rup1->down,rup2=rup2->down; } } for(register int i=1;i<=n;i++){ node *p=pos[i][0]; for(register int j=1;j<=m;j++){ p=p->right; W(p->val);putchar(' '); } putchar('\n'); }}
本题结。
- [NOIP2017模拟]裁剪表格
- NOIP模拟 裁剪表格【链表】
- [NOIP模拟][链表]裁剪表格
- NOIP模拟:裁剪表格(链表)
- NOIP模拟(10.20)T3 裁剪表格
- NOIP2017模拟赛1
- NOIP2017模拟赛8
- NOIP2017模拟赛9
- [NOIP2017模拟]切蛋糕
- [NOIP2017模拟]随机图
- [NOIP2017模拟]能源
- [NOIP2017模拟]电影
- [NOIP2017模拟]鸭舌
- [NOIP2017模拟]permut
- [NOIP2017模拟]beautiful
- [NOIP2017模拟]路径
- [NOIP2017模拟]流
- [NOIP2017模拟]subset
- 1701H5 范江睿 10月20日 连续第10天总结
- Infinite monkey theorem
- 【Python】使用openCV与dlib实现人脸68特征点的检测与手动修改
- 15算法课程 110. Balanced Binary Tree
- 解决virtualBox虚拟机不可使用问题
- [NOIP2017模拟]裁剪表格
- [树链剖分] [bzoj2243] [SDOI2011]染色
- 浏览器渲染机制之DOM树
- java实现map和object互转的三种方法
- [noip2016]组合数问题 题解
- Linux装机必备(centos)
- C++笔记——公有继承、私有继承、保护继承、多重继承
- 堆栈实现表达式求值
- 判断素数