solved 3 (7/22)
前缀和乱搞的题看成是模拟退火求最小费马点,很烦。
C Permutations (子序列)
D Travel Frog (dp + 公式)
H Appositive Body (中心对称的结论)
<qj>
题意:4维空间里n个点,是否能够中心对称。
首先利用所有点求出中心点的坐标,然后对于每个点,求出对应点的坐标,在set中查找是否存在。
所有的点都有对应点,那么存在。
#include <cstdio> #include <iostream> #include <set> using namespace std; #define ll long long template<class T> inline void read(T &ret){ int sign = 1; ret=0; char c = getchar(); while(c!='-' && (c>'9'||c<'0'))c=getchar(); if(c=='-')sign=-1; else ret = c-'0'; while(c=getchar(),c>='0'&&c<='9'){ ret = ret*10+c-'0'; } ret*=sign; } int n; struct node{ ll x,y,z,t; node(ll x=0,ll y=0,ll z=0,ll t=0):x(x),y(y),z(z),t(t){} friend bool operator < (node a,node b){ if(a.x==b.x){ if(a.y==b.y){ if(a.z==b.z){ return a.t<b.t; }return a.z<b.z; }return a.y<b.y; }return a.x<b.x; } friend bool operator == (node a,node b){ if(a.x==b.x&&a.y==b.y&&a.z==b.z&&a.t==b.t)return 1; return 0; } }p[10000007]; multiset<node> st; node findnode(node a,node b){ ll xx = b.x*2-a.x; ll yy = b.y*2-a.y; ll zz = b.z*2-a.z; ll tt = b.t*2-a.t; return node(xx,yy,zz,tt); } int main(){ while(scanf("%d",&n)!=EOF){ ll sumx=0,sumy=0,sumz=0,sumt=0; for(int i=1;i<=n;i++){ scanf("%lld %lld %lld %lld",&p[i].x,&p[i].y,&p[i].z,&p[i].t); //read(p[i].x);read(p[i].y); //read(p[i].z);read(p[i].t); sumx+=p[i].x; sumy+=p[i].y; sumz+=p[i].z; sumt+=p[i].t; } st.clear(); node zx = node(sumx,sumy,sumz,sumt); for(int i=1;i<=n;i++){ p[i].x*=n;p[i].y*=n; p[i].z*=n;p[i].t*=n; st.insert(p[i]); } int ans=1; for(int i=1;i<=n;i++){ node dc = findnode(p[i],zx); //cout<<st.count(dc)<<" "<<st.count(p[i])<<endl; if(st.count(dc)==0){ ans=0;break; } } if(ans)puts("exist"); else puts("not exist"); } return 0; }
I 统帅三军! (前缀和乱搞)