求助普及月赛T4
查看原帖
求助普及月赛T4
236862
Miraik楼主2022/3/21 07:52

RT,赛时代码,只能过小样例

#include<bits/stdc++.h>
//#define int ll
#define pb push_back
#define mp make_pair
#define sec second
#define fir first
#define pii pair<int,int>
#define piii pair<int,pair<int,int> >
using namespace std;
typedef long long ll;
const int N=2005;
const int inf=(1<<30)-1;
const ll inff=1ll<<60;
const int mod=1e9+7;
inline int read(){
	int x=0,f=1;char c=getchar();
	while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
	while(c>='0'&&c<='9'){x=(x<<1)+(x<<3)+(c^48);c=getchar();}
	return x*f;
}
int n,m,a[N][N],all,bac[N],lit,row;
void output(int x,int y){
//	printf("x,y:%d %d\n",x,y);
	printf("%d ",a[x][y]);
	if(x == all && y == bac[all]) return;
	if(x<n) output(x+1,y); 
	else{
		if(y==1 || x==all){
			row++;
			if(bac[lit] < row) lit++;
			output(lit,row);
		}
		else output(x+1,y-1);
	}
}
void out(){
	for(int i=1;i<=all;i++)
	    for(int j=1;j<=bac[i];j++)
	        printf("%d%c",a[i][j],j==bac[i]?'\n':' ');
}
int main(){int tests=1;//tests=read();
while(tests--){
//	freopen("a.in","r",stdin);
//	freopen("a.txt","w",stdout);
	n=read(),m=read();
	all=2*n-1;
	for(int i=1;i<=all;i++)
		bac[i]=2*n-1-abs(n-i);
//	for(int i=1;i<=all;i++) printf("i:%d bac:%d\n",i,bac[i]);
	for(int i=1;i<=m;i++){
		int x=read(),y=read(),z=read(),r=read(),k=read();
		if(x==0){
			x=n-y;
			y=n-z;
		}
		else if(y==0){
			x=n+x;
			y=n-z;
		}
		else{
			int tmp=n+x;
			x=n-y;
			y=tmp;
		}
//		printf("centre %d %d\n",x,y);
//      找到每次操作对应的中心点
//      r 是 半径,tim 是处理的层数
//      问题应该就在下面差分这块,但不知道错在哪了
        r--;
        int le=x-r,ri=x+r;
        int len=ri-le+1,tim=1;
        if(le<1){
        	tim += 1-le;
			le=1;
        }
        if(ri>all) ri=all;
//      int bl=y-r,br=y,mid=0;
        int bl,br;
        if(x <= n) bl=y-r,br=y;
        else br=y+(x-max(le,n)),bl=br-r;
        // 求第一层的左右端点
        for(int i=le;i<=ri;i++){
//        	printf("i:%d bl:%d br:%d\n",i,bl,br);
        	a[i][max(1,bl)]+=k;
        	a[i][min(bac[i],br)+1]-=k;
        	if(i<n){
        		if(tim<=len/2) br++;
        		else bl++;
        	}
        	else{
        		if(tim<=len/2) bl--;
        		else br--;
        	}
            // 移动左右端点,在 i<n 时左移,i>n 时右移
        	tim++;
        }
	}
	for(int i=1;i<=all;i++)
	    for(int j=1;j<=bac[i];j++)
	        a[i][j] += a[i][j-1];
	row=lit=1;
	output(1,1); //应该没问题的输出
//    out();
}	return 0;
}
/*
4 3
0 1 1 3 4
3 0 3 4 3
1 0 0 2 2
*/
2022/3/21 07:52
加载中...