这题其实蛮水的?ios
题意就是说:c++
给定一个 1~n 的序列,每次挑两个数 x y 合并,合并值为 \(x+y+xy\) ,而后求不断合并最后剩下的一个的最大值git
随便搞搞发现答案应该是不管怎么合并都同样的,因此从左到右合并就行了,加上是第一题,大概就是这个结论ui
因而前缀信息处理一下每次直接输出就行了...spa
//by Judge #include<bits/stdc++.h> #define Rg register #define fp(i,a,b) for(Rg int i=(a),I=(b)+1;i<I;++i) using namespace std; const int mod=1e9+7; const int M=1e6+3; typedef int arr[M]; #ifndef Judge #define getchar() (p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<21,stdin),p1==p2)?EOF:*p1++) #endif char buf[1<<21],*p1=buf,*p2=buf; inline int read(){ int x=0,f=1; char c=getchar(); for(;!isdigit(c);c=getchar()) if(c=='-') f=-1; for(;isdigit(c);c=getchar()) x=x*10+c-'0'; return x*f; } char sr[1<<21],z[20];int CCF=-1,Z; inline void Ot(){fwrite(sr,1,CCF+1,stdout),CCF=-1;} inline void print(int x,char chr='\n'){ if(CCF>1<<20)Ot();if(x<0)sr[++CCF]=45,x=-x; while(z[++Z]=x%10+48,x/=10); while(sr[++CCF]=z[Z],--Z);sr[++CCF]=chr; } int n; arr q,f; inline int mul(Rg int x,Rg int y){return 1ll*x*y%mod;} inline int inc(Rg int x,Rg int y){return (x+=y)>=mod?x-mod:x;} int main(){ Rg int T=read(); fp(i,1,T) q[i]=read(); n=*max_element(q+1,q+1+T); fp(i,1,n) f[i]=inc(inc(f[i-1],i),mul(i,f[i-1])); fp(i,1,T) print(f[q[i]]); return Ot(),0; }
给出两堆火柴,每次取某堆火柴的必定数,这个数字要能整除另外一堆火柴的个数,谁先取完某一堆的获胜code
貌似是博弈论,看看这整除好像和 gcd 颇有关的样子,因而发现先掌握主动权的人必胜(就是说轮到某人取的时候,某一堆火柴整除另外一堆火柴的个数大于 1 ,那么这我的就能够彻底控制局面了),而后加些特判就 ok 了,复杂度带个 log 但常数真的小element
//by Judge #include<cstdio> #include<cstring> #include<iostream> #define Rg register #define fp(i,a,b) for(Rg int i=(a),I=(b)+1;i<I;++i) #define ll long long using namespace std; #ifndef Judge #define getchar() (p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<21,stdin),p1==p2)?EOF:*p1++) #endif char buf[1<<21],*p1=buf,*p2=buf; inline ll read(){ ll x=0,f=1; char c=getchar(); for(;!isdigit(c);c=getchar()) if(c=='-') f=-1; for(;isdigit(c);c=getchar()) x=x*10+c-'0'; return x*f; } ll n,m,ans; #define swap(a,b) (a)^=(b)^=(a)^=(b) int main(){ fp(i,1,read()){ n=read(),m=read(); if(n<m) swap(n,m); ans=1; if(n%m==0){ puts("Ari"); goto end; } while(n<m<<1) n-=m,swap(n,m),ans^=1; puts(ans?"Ari":"Rich"); end:; } return 0; }
给出 n 个二维点,你能够放置 n-1 条斜率为 1 或 -1 的直线,而后要让全部点里最近的直线距离中的最大值最小,并输出这个最小值乘上根号 2 的值,即求
\[ans=\sqrt2Min(~~~ MAX_{i=1}^n(dis _ i )~~~ )\]get
而后咱们发现只要求出全部的两个点之间的 \({||x1-x2| -|y1-y2|| \over 2} + Min(|x1-x2|,|y1-y2|)\) 的最小值博客
然鹅 \(n^2\) 枚举就完蛋了,因而咱们发现只须要通过每一个点记录下该点的两条斜率为 -1 和 1 的直线,而后全部斜率相同的直线排个序,求两条相邻直线 \(y_1=(±1)x_1+b_1,y_2=(±1)x_2+b_2\) 中 \(|b_2-b_1|\)的最小差值就是答案了string
//by Judge #include<cstdio> #include<cstring> #include<iostream> #include<algorithm> #define Rg register #define fp(i,a,b) for(Rg int i=(a),I=(b)+1;i<I;++i) using namespace std; const int M=1e4+3; typedef int arr[M]; #ifndef Judge #define getchar() (p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<21,stdin),p1==p2)?EOF:*p1++) #endif char buf[1<<21],*p1=buf,*p2=buf; inline bool cmin(int& a,int b){return a>b?a=b,1:0;} inline int read(){ int x=0,f=1; char c=getchar(); for(;!isdigit(c);c=getchar()) if(c=='-') f=-1; for(;isdigit(c);c=getchar()) x=x*10+c-'0'; return x*f; } int n,ans; arr x,y,a,b; int main(){ fp(i,1,read()){ n=read(),ans=1e9; fp(i,1,n) x[i]=read(),y[i]=read(),a[i]=y[i]-x[i],b[i]=x[i]+y[i]; sort(a+1,a+1+n),sort(b+1,b+1+n); fp(i,2,n) cmin(ans,a[i]-a[i-1]),cmin(ans,b[i]-b[i-1]); printf("%.8lf\n",ans/2.0); } return 0; }
关于其余题目可能能够看看博主博客园里面有没有写