跳房子题解(分块+贪心/线段树)[九校联考][NOIP模拟]

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接: https://blog.csdn.net/qq_37555704/article/details/98645239

文章目录

题目

在这里插入图片描述在这里插入图片描述在这里插入图片描述在这里插入图片描述

思路

代码

#include<bits/stdc++.h>
#define LL long long
using namespace std;
int read(){
	bool f=0;int x=0;char c=getchar();
	while(c<'0'||'9'<c){if(c=='-')f=1;c=getchar();}
	while('0'<=c&&c<='9') x=(x<<3)+(x<<1)+(c^48),c=getchar();
	return !f?x:-x;
}
#define MAXN 2000
char S[10];
int a[MAXN+5][MAXN+5],vis[MAXN+5][MAXN+5];
int main(){
	//freopen("jump.in","r",stdin);
	//freopen("jump.out","w",stdout);
	int n=read(),m=read();
	for(int i=1;i<=n;i++)
		for(int j=1;j<=m;j++)
			a[i][j]=read();
	int Q=read(),p=1,q=1;
	for(register int i=1;i<=Q;i++){
		scanf("%s",S);
		if(S[0]=='m'){
			register int k=read(),cnt=0;
			vis[p][q]=i;
			while(1){
				int t1=q-1,t2=q,t3=q+1;
				p++;
				if(p>m) p-=m;
				if(t1<=0) t1+=m; 
				if(t3>m) t3-=m;
				if(a[p][t1]>max(a[p][t2],a[p][t3]))
					q=t1;
				else if(a[p][t2]>max(a[p][t1],a[p][t3]))
					q=t2;
				else q=t3;
				cnt++,k--;
				if(!k||vis[p][q]%10000==i) break;
				vis[p][q]=cnt*10000+i;
			}
			k%=cnt-vis[p][q]/10000;
			while(k){
				int t1=q-1,t2=q,t3=q+1;
				p++;
				if(p>m) p-=m;
				if(t1<=0) t1+=m; 
				if(t3>m) t3-=m;
				if(a[p][t1]>max(a[p][t2],a[p][t3]))
					q=t1;
				else if(a[p][t2]>max(a[p][t1],a[p][t3]))
					q=t2;
				else q=t3;
				k--;
			}
			printf("%d %d\n",p,q);
		}
		else{
			register int x=read(),y=read(),p=read();
			a[x][y]=p;
		}
	}
	return 0;
}
#include<bits/stdc++.h>
#define LL long long
using namespace std;
int read(){
	bool f=0;int x=0;char c=getchar();
	while(c<'0'||'9'<c){if(c=='-')f=1;c=getchar();}
	while('0'<=c&&c<='9') x=(x<<3)+(x<<1)+(c^48),c=getchar();
	return !f?x:-x;
}
#define MAXN 2000
#define INF 0x3f3f3f3f
inline int check(int x,int Mod){return (x%Mod+Mod)%Mod;}
int n,m,a[MAXN+5][MAXN+5],nxt[MAXN+5];
int Next(int x,int y){
	int Max=-1,p=-1;
	for(int i=x-1;i<=x+1;i++){
		int tmp=a[check(i,n)][check(y+1,m)];
		if(tmp>Max)
			Max=tmp,p=i;
	}
	return p;
}
int Get_Nxt(int x,int y){
	do{
		x=check(Next(x,y++),n);
	}while(check(y,m));
	return x;
}
void Change(int x,int y){
	int L=x,R=x,To=Get_Nxt(x,y);
	int j=check(y,m);//!!!!!!!!
	while(j>0){//!! for(int j=check(y-1,m);j>=0;j--){
		j--;
		int tL=INF,tR=-INF;//!!!!!!!! ?????!!
		for(int i=L-1;i<=L+1;i++){
			int tmp=Next(i,j);
			if(L<=tmp&&tmp<=R){
				tL=i;
				break;
			}
		}
		for(int i=R+1;i>=R-1;i--){
			int tmp=Next(i,j);
			if(L<=tmp&&tmp<=R){
				tR=i;
				break;
			}
		}
		if(tR<tL)
			return ;
		L=tL,R=tR;
	}
	if(R-L+1>=n)
		for(int i=0;i<n;i++)
			nxt[i]=To;
	else
		for(int i=L;i<=R;i++)
			nxt[check(i,n)]=To;
	return ;
}
int vis[MAXN+5];
int main(){
	//freopen("jump.in","r",stdin);
	//freopen("jump.out","w",stdout);
	n=read(),m=read();
	for(int i=0;i<n;i++)
		for(int j=0;j<m;j++)
			a[i][j]=read();
	for(int i=0;i<n;i++)
		nxt[i]=Get_Nxt(i,0);
	char S[20];
	int Q=read(),p=0,q=0;
	for(int t=1;t<=Q;t++){
		scanf("%s",S);
		if(S[0]=='m'){
			int k=read();
			while(k&&check(q,m))
				p=Next(p,q),q++,k--;
			memset(vis,0,sizeof(vis));
			p=check(p,n),q=check(q,m);
			vis[p]=k;
			while(k>=m){
				p=nxt[p],k-=m;
				if(vis[p])
					k%=vis[p]-k;
				vis[p]=k;
			}
			//while(m<=k)
			//	p=nxt[check(p,n)],k-=m;
			while(k)
				p=Next(p,q),q++,k--;
			printf("%d %d\n",check(p,n)+1,check(q,m)+1);
		}
		else{
			int x=read()-1,y=read()-1,v=read();
			a[x][y]=v;
			for(int i=x-1;i<=x+1;i++)
				Change(check(i,n),check(y-1,m));
		}
	}
	return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_37555704/article/details/98645239