ZOJ Monthly, January 2019 Little Sub and his Geometry Problem ZOJ4082(模拟 乱搞)
在一次被自己秀死...
题目: 给出N,K, Q;
给出一个N*N的矩阵 , 与K个特殊点 , 与Q次查询 , 每次查询给出一个C , 问 在这个N*N矩阵中 , 有多少的点是满足这样的一个关系
问题转换就是说 , 当前的坐标X,Y , 满足一个(X+Y)*cnt - sumxy ; 的关系 , cnt 是指在X,Y这个位置 , 有多少个特殊点会被计算到 , sumXY是满足条件的特殊点的横纵坐标的和 ,;
分析: 经过一些分析后 ,你可以得出一个这样的结论 , 在我查询C 的时候 ,对于放程(X+Y)*cnt - sumxy==C ,随着X的增大 , Y是不断的被减小 , 也就是说 假设我在(X1,Y1 ) 与(X2,Y2) X1<X2是可以满足的 , 那么我们一定是可以得出 Y1<Y2 , 无论X1到X2之间是有多少的特殊点都是如此 , 为什么吗呢? 对于X1 ,X2 如果在X2时满足的特殊点是多的 , 那Y2是不是就一定比Y1要小 ; 所以我们可以依据这样的特性 ,我们枚举一遍(X=1;X<=N ) 这个是当前点的横坐标 ,我同时也枚举Y , 注意 ,因为Y是不会增加的所以 可以把Y看出是指针 , 指向当前X拥有的最大Y;
复制度也就是Q(N+Y+K) Q就10 ,可以过
现在来说说为什么被秀死 , DUG了许久 PE , 说是格式错误,最终找到 ,原来是puts("") 与puts(" ") , 我为了好看习惯性的在里面打了个空格 ,。。。我日..
#include<bits/stdc++.h> using namespace std ; #define N 100001 #define ll long long int n,k; ll Ysum[N],Ycout[N]; ll ANS[20]; struct no { int x,y; }a[N]; bool cmp(no a , no b) { if(a.x!=b.x) return a.x<b.x; return a.y<b.y; } ll solve(ll C) { memset(Ysum,0,sizeof(Ysum)); memset(Ycout,0,sizeof(Ycout)); int id=1; ll Y=n; ll cnt=0,sum=0; int num=0; for(ll X=1 ; X<=n ; X++) { while(a[id].x<=X && id<=k) { if(Y>=a[id].y) { cnt++; sum+=a[id].x+a[id].y; Ysum[a[id].y]+=a[id].x+a[id].y; Ycout[a[id].y]++; } id++; } while((X+Y)*cnt-sum>C) { cnt-=Ycout[Y];///有了这些数组我才能知道我CNT , sum应该减去什么 sum-=Ysum[Y]; Y--; } if((X+Y)*cnt-sum==C) num++; } return num; } int main() { int t; scanf("%d",&t); while(t--) { scanf("%d%d",&n,&k); for(int i=1 ; i<=k ; i++) { scanf("%d%d",&a[i].x , &a[i].y); } sort(a+1,a+1+k,cmp); int Q; scanf("%d",&Q); ll sum=0; ll C; for(int i=1 ; i<=Q ; i++) { scanf("%lld",&C); if(i!=1) putchar(' '); printf("%lld",solve(C)); } puts(""); } return 0; }