AB略。
C,结论是把排列弄成L段,使得n除以L上取整加上L最小。
#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
using namespace std;
int main()
{
int n,a=0,s=1000000;scanf("%d",&n);
for(int i=1;i<=n;i++)
if((n-1)/i+1+i<s) s=(n-1)/i+1+i,a=i;
for(int i=1;i<=n/a;i++)
for(int j=i*a;j>(i-1)*a;j--)
printf("%d ",j);
for(int i=n;i>n/a*a;i--) printf("%d ",i);
return !printf("\n");
}
D,尽管std是2的1.5次方的,但实际上你写个2的2n次也能过。
#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
#define gc getchar()
#define lint long long
#define debug(x) cerr<<#x<<"="<<x
#define sp <<" "
#define ln endl
#define S 10010
using namespace std;
inline int inn()
{
int x,ch;while((ch=gc)<'0'||ch>'9');
x=ch^'0';while((ch=gc)>='0'&&ch<='9')
x=(x<<1)+(x<<3)+(ch^'0');return x;
}
int cnt[S],ans[S],val[S][110],w[100];
int main()
{
int n=inn(),m=inn(),q=inn();
for(int i=1;i<=n;i++) w[i]=inn();
for(int i=1;i<=m;i++)
{
int v=0;
for(int j=0;j<n;j++)
{
int x;while((x=gc)!='0'&&x!='1');
v|=(x-'0')<<j;
}
cnt[v]++;
}
for(int i=0;i<(1<<n);i++)
{
for(int j=0;j<n;j++)
if(!((i>>j)&1)) ans[i]+=w[j+1];
ans[i]=min(ans[i],101);
}
for(int i=0;i<(1<<n);i++)
for(int j=0;j<(1<<n);j++)
val[i][ans[i^j]]+=cnt[j];
for(int i=0;i<(1<<n);i++)
for(int j=1;j<=100;j++)
val[i][j]+=val[i][j-1];
while(q--)
{
int v=0;
for(int j=0;j<n;j++)
{
int x;while((x=gc)!='0'&&x!='1');
v|=(x-'0')<<j;
}
int k=inn();printf("%d\n",val[v][k]);
}
return 0;
}
E,计算几何,那个变换其实就是生成两个凸包,最后问两个凸包是否完全一样。按照固定顺序提取边和角看序列是否循环同构即可。
#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
#include<vector>
#define db long long
#define debug(x) cerr<<#x<<"="<<x
#define sp <<" "
#define ln <<endl
#define gc getchar()
#define N 1000010
using namespace std;
inline int inn()
{
int x,ch;while((ch=gc)<'0'||ch>'9');
x=ch^'0';while((ch=gc)>='0'&&ch<='9')
x=(x<<1)+(x<<3)+(ch^'0');return x;
}
inline int sgn(db x) { return (x<0)?-1:(x>0); }
inline int sgn(db x,db y) { return sgn(x-y); }
inline db gabs(db x) { return x<0?-x:x; }
struct P{
db x,y;P(db _x=0,db _y=0) { x=_x,y=_y; }
inline P operator=(const P &p) { x=p.x,y=p.y;return *this; }
inline bool operator<(const P &p)const { return sgn(x-p.x)?x<p.x:y<p.y; }
inline P operator+(const P &p)const { return P(x+p.x,y+p.y); }
inline P operator-(const P &p)const { return P(x-p.x,y-p.y); }
inline int init() { return x=inn(),y=inn(),0; }
};
typedef P V ;
inline db dot(const V &v1,const V &v2) { return v1.x*v2.x+v1.y*v2.y; }
inline db dot(const P &s,const P &p1,const P &p2) { return dot(p1-s,p2-s); }
inline db cross(const V &v1,const V &v2) { return v1.x*v2.y-v1.y*v2.x; }
inline db cross(const P &s,const P &p1,const P &p2) { return cross(p1-s,p2-s); }
inline db Len2(const V &v) { return dot(v,v); }
inline vector<P> convexHull(vector<P> ps,int need_sort=1)
{
int n=(int)ps.size();if(n<=1) return ps;
vector<P> ans(2*n);int k=0;
if(need_sort) sort(ps.begin(),ps.end());
for(int i=0;i<n;ans[k++]=ps[i++])
while(k>1&&sgn(cross(ans[k-2],ans[k-1],ps[i]))<=0) k--;
for(int i=n-1,t=k;i>=0;ans[k++]=ps[i--])
while(k>t&&sgn(cross(ans[k-2],ans[k-1],ps[i]))<=0) k--;
ans.resize(k-1);return ans;
}
vector<P> A,B;
inline int getList(vector<P> &ps,db *S)
{
int ss=0,n=(int)ps.size();
for(int i=0;i<n;i++)
{
P A=ps[(i+1)%n],B=ps[i],C=ps[(i+2)%n];
S[++ss]=Len2(B-A),S[++ss]=dot(A,B,C);
}
return ss;
}
int nxt[N];db S[N],T[N];
inline int getnxt(db *s,int n)
{
for(int i=2;i<=n;i++)
{
int &j=nxt[i];j=nxt[i-1];
while(j&&sgn(s[j+1]-s[i])) j=nxt[j];
if(sgn(s[j+1]-s[i])==0) j++;
}
return 0;
}
inline int ocr(db *s,int n,db *t,int m)
{
for(int i=1,j=0;i<=n;i++)
{
while(j&&sgn(t[j+1]-s[i])) j=nxt[j];
if(sgn(t[j+1]-s[i])==0) j++;
if(j==m) return 1;
}
return 0;
}
int main()
{
int n=inn(),m=inn();A.resize(n),B.resize(m);
for(int i=0;i<n;i++) A[i].init();
for(int i=0;i<m;i++) B[i].init();
A=convexHull(A),B=convexHull(B);
if(A.size()!=B.size()) return !printf("NO\n");
int slen=getList(A,S),tlen=getList(B,T);
for(int i=slen+1;i<slen*2;i++) S[i]=S[i-slen];
slen=slen*2-1,getnxt(T,tlen);
if(ocr(S,slen,T,tlen)) return !printf("YES\n");
return !printf("no\n");
}