不要相信这篇题解的任何一个字,包括标题和这句话。
省流-恶搞题目:A,B,C,M,Q。
A
思路
这道题实在是太难啦,蒟蒻想了半天只能用 ASCLL 码做。
AC code
#include<bits/stdc++.h>
using namespace std;
int main()
{
char s[13]={72,101,108,108,111,44,87,111,114,108,100,33};
printf("%s",s);
return 0;
}
B
思路
实在是太难了,比第一题还要难,没有想到 \(O(1)\) 的做法,只想到了 \(O(\log 5)\) 的线段树。
很容易想到,区间修改 \([1,a]\) 和 \([1,b]\),然后再区间查询,但是发现 \(a,b\) 太大,开不了那么大的线段树。所以换一种思路。
发现只需要区间查询就好,所以还算是比较水的线段树。
AC code
#include<bits/stdc++.h>
using namespace std;
struct node{int l,r,sum,len,tag;}t[20];
int a[20];
inline void pushup(int p){t[p].sum=t[p<<1].sum+t[p<<1|1].sum;}
inline void pushdown(int p)
{
t[p<<1].sum+=t[p<<1].len*t[p].tag,t[p<<1|1].sum+=t[p<<1|1].len*t[p].tag,t[p<<1].tag+=t[p].tag,t[p<<1|1].tag+=t[p].tag,t[p].tag=0;
}
void build(int p,int l,int r)
{
t[p].l=l,t[p].r=r,t[p].len=r-l+1;
if(l==r){t[p].sum=a[l];return;}
int mid=l+r>>1;
build(p<<1,l,mid),build(p<<1|1,mid+1,r);
pushup(p);
}
/*本题不需要的函数*/
void update(int p,int l,int r,int k)
{
if(t[p].l>=l&&t[p].r<=r){t[p].sum+=t[p].len*k,t[p].tag+=k;return;}
if(t[p].tag) pushdown(p);
int mid=t[p].l+t[p].r>>1;
if(mid>=l) update(p<<1,l,r,k);
if(mid<r) update(p<<1|1,l,r,k);
pushup(p);
}
int ask(int p,int l,int r)
{
if(t[p].l>=l&&t[p].l<=r) return t[p].sum;
if(t[p].tag) pushdown(p);
int mid=t[p].l+t[p].r>>1,ans=0;
if(mid>=l) ans=ask(p<<1,l,r);
if(mid<r) ans+=ask(p<<1|1,l,r);
return ans;
}
int main()
{
scanf("%d%d",&a[1],&a[2]);
build(1,1,4);
printf("%d",ask(1,1,4));
return 0;
}
C
思路
容易发现这道题可以把每一位都看作函数的某一项,然后相乘就是函数多项式相乘,所以很容易地想到 FFT。
AC code
#include<cstdio>
#include<cmath>
#include<algorithm>
#include<cstring>
#include<iostream>
#define ll long long
using namespace std;
const int N=10000005,M=998244353,G=3,Gi=332748118;
ll a[N],b[N],c[N],ans[N];
int cnt=1,l,r[N];
string s1,s2;
ll fbow(ll a,ll b){
ll ans=1;
while(b){
if(b&1) ans=(ans*a)%M;
a=(a*a)%M;
b>>=1;
}
return ans;
}
void ntt(ll *A,int t){
for(ll i=0;i<cnt;i++) if(i<r[i]) swap(A[i],A[r[i]]);
for(ll mid=1;mid<cnt;mid*=2){
ll wn;
if(t==1) wn=fbow(G,(M-1)/(mid*2));
else wn=fbow(Gi,(M-1)/(mid*2));
for(ll j=0;j<cnt;j+=(mid*2)){
ll w=1;
for(ll k=0;k<mid;k++,w=(w*wn)%M){
ll x=A[j+k],y=w*A[j+mid+k]%M;
A[j+k]=(x+y)%M;
A[j+k+mid]=(x-y+M)%M;
}
}
}
}
int main(){
cin.tie(0),cin.tie(0);
cin>>s1>>s2;
ll len1=s1.size(),len2=s2.size(),tt=0;
for(ll i=len1-1;i>=0;i--) a[++tt]=s1[i]-48;
tt=0;
for(ll i=len2-1;i>=0;i--) b[++tt]=s2[i]-48;
while(cnt<=len1+len2) cnt*=2,l++;
for(ll i=0;i<cnt;i++) r[i]=(r[i>>1]>>1)|((i&1)<<(l-1));
ntt(a,1);ntt(b,1);
for(ll i=0;i<=cnt;i++) c[i]=(a[i]*b[i])%M;
ntt(c,-1);
ll inv=fbow(cnt,M-2);
for(int i=0;i<=cnt;i++){
ans[i]+=(ll)(c[i]*inv)%M;
if(ans[i]>=10){
ans[i+1]+=ans[i]/10;
ans[i]%=10;
cnt+=(i==cnt);
}
}
while(!ans[cnt]&&cnt>=1) cnt--;
cnt++;
while(--cnt>=2) cout<<ans[cnt];
return 0;
}
D
思路
非常的难,蒟蒻想了半天才做出来。
AC code
#include<iostream>
#include<cmath>
using namespace std;
int main()
{
int h,r;cin>>h>>r;
const double v=20000/(3.14*r*r*h);
cout<<ceil(v);
return 0;
}
E
思路
需要小学奥数,对于本蒟蒻来说实在是太难了。
AC code
#include<bits/stdc++.h>
using namespace std;
int main()
{
int a,b,n;
cin>>a>>b>>n;
cout<<(b-a)*(n-1)+a;
return 0;
}
F
思路
居然是普及组地题目,哇哇哇,对蒟蒻来说太难啦。抠破脑袋才想出来。
AC code
#include<bits/stdc++.h>
using namespace std;
int a,b,c;
int main()
{
cin>>a>>b>>c;
cout<<0.2*a+0.3*b+0.5*c;
}
G
思路
虽然较简单,但是对于蒟蒻而言实在是太难了。
AC code
#include<bits/stdc++.h>
using namespace std;
int a;
int main()
{
cin>>a>>a;
cout<<a;
return 0;
}
H
思路
哇,向零取整,怎么办啊,对蒟蒻来说实在是没天理地难。
AC code
#include<cstdio>
using namespace std;
int main(){
double a;
scanf("%lf",&a);
printf("%d",(int)a);
return 0;
}
I
思路
怎么上表达式了,难得蒟蒻哇哇叫。
AC code
#include<cstdio>
using namespace std;
int main(){
int a,b,c;
scanf("%d%d%d",&a,&b,&c);
printf("%d",(a+b)*c);
return 0;
}
J
思路
太难啦,蒟蒻只能想到用字符串做。
AC code
#include<bits/stdc++.h>
using namespace std;
char s[1145141];
int main()
{
scanf("%s",s+1);
for(int i=s.size();i>0;--i) printf("%c",s[i]);
return 0;
}
K
思路
我测,⚪!
太难啦!!!
AC code
#include<bits/stdc++.h>
using namespace std;
const double pi=3.14159;
double r;
int main()
{
scanf("%lf",&r);
printf("%.4lf %.4lf %.4lf",r*2,r*2*pi,r*r*pi);
}
L
思路
怎么回事,还有三次方程,难难难!
AC code
#include<bits/stdc++.h>
using namespace std;
double x,a,b,c,d;
int main()
{
scanf("%lf%lf%lf%lf%lf",&x,&a,&b,&c,&d);
printf("%.7lf",a*x*x*x+b*x*x+c*x+d);
}
M
思路
哇,一看就是计算几何,直接上模板,用叉积算面积。
AC code
//计算几何模板:https://www.luogu.com.cn/blog/AuroraWind/ji-suan-ji-he-mu-ban-dian-xiang-liang-xian
#include<bits/stdc++.h>
using namespace std;
const double eps=1e-8,pi=acos(-1.0);
const int N=100005;
inline int dcmp(double x){return (x<-eps)?-1:(x>eps)?1:0;}//判断正负
inline double dabs(double x){return x*dcmp(x);}//绝对值
/*向量(点)*/
struct vec{double x,y;vec(double _x=0,double _y=0){x=_x;y=_y;}};
inline bool cmp_vec(vec a,vec b){return (a.x!=b.x)?a.x<b.x:a.y<b.y;}
inline double len(vec a){return sqrt(a.x*a.x+a.y*a.y);}//模长
inline double ang(vec a){return atan2(a.y,a.x);}//角度
inline vec operator +(const vec &a,const vec &b){return vec(a.x+b.x,a.y+b.y);}
inline vec operator -(const vec &a,const vec &b){return vec(a.x-b.x,a.y-b.y);}
inline vec operator *(const vec &a,const double &b){return vec(a.x*b,a.y*b);}
inline vec operator /(const vec &a,const double &b){return vec(a.x/b,a.y/b);}
inline double operator *(const vec &a,const vec &b){return a.x*b.x+a.y*b.y;}//点积
inline double operator ^(const vec &a,const vec &b){return a.x*b.y-a.y*b.x;}//叉积
inline vec rot(vec a,double the){return vec(a.x*cos(the)-a.y*sin(the),a.x*sin(the)+a.y*cos(the));}//旋转
inline vec rot90(vec a){return vec(a.y,-a.x);}//特殊角旋转
inline vec rotpt(vec a,vec b,double the){return b+rot(a-b,the);}//a绕b旋转
/*线*/
struct line{vec s,t;line(vec _s=vec(0,0),vec _t=vec(0,0)){s=_s;t=_t;}};//线
inline double maxx(line l){return max(l.s.x,l.t.x);}//大x
inline double maxy(line l){return max(l.s.y,l.t.y);}//大y
inline double minx(line l){return min(l.s.x,l.t.x);}//小x
inline double miny(line l){return min(l.s.y,l.t.y);}//小y
inline double ang(line l){return ang(l.t-l.s);}//角度
inline bool operator <(line &a,line &b){double a1=ang(a.t-a.s),a2=ang(b.t-b.s);return (dcmp(a2-a1))?a2>a1:dcmp((a.t-a.s)^(b.t-b.s))<0;}
inline bool operator ==(vec &a,vec &b){return (!dcmp(a.x-b.x)&&!dcmp(a.y-b.y));}//点是否相等
inline double dis(vec a,vec b){return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y));}//点距离
inline bool pd_pl(vec a,line b){return !dcmp((a-b.s)^(b.t-b.s));}//点是否在直线上
inline bool pd_px(vec a,line b){return pd_pl(a,b)&&(dcmp((a-b.s)*(a-b.t))<=0);}//点是否在线段上
inline vec footpt(vec a,line b){vec x=a-b.s,y=a-b.t,z=b.t-b.s;double s1=x*z,s2=-1.0*(y*z);return b.s+z*(s1/(s1+s2));}//求垂足(分别求as,at关于st的投影)
inline vec mirror(vec a,line b){return a+(footpt(a,b)-a)*2.0;}//a关于b的对称点
inline double dis_pl(vec a,line b){return dabs((a-b.s)^(a-b.t))/len(b.t-b.s);}//求a到直线b的距离(面积除以底边长)
inline double dis_px(vec a,line b){return (dcmp((a-b.s)*(b.t-b.s))<0)?len(a-b.s):(dcmp((a-b.t)*(b.t-b.s))>0)?len(a-b.t):dis_pl(a,b);}//求a到线段b的距离
inline vec pt_px(vec a,line b){return (dcmp((a-b.s)*(b.t-b.s))<0)?b.s:(dcmp((a-b.t)*(b.t-b.s))>0)?b.t:footpt(a,b);}//在线段b上与a最近的点
inline vec cross(line a,line b){vec x=a.t-a.s,y=b.t-b.s,z=a.s-b.s;return a.s+x*((y^z)/(x^y));}//求a与b的交点
inline bool pd_cross_lx(line a,line b){return (!dcmp((a.t-a.s)^(b.t-b.s)))?0:pd_px(cross(a,b),a);}//线段a与直线b是否相交
inline bool pd_cross_xx(line a,line b){return pd_cross_lx(a,b)&&pd_cross_lx(b,a);}//判断线段a是否与线段b相交
inline bool pd_cross_xx_(line a,line b)//判断两线段是否相交 (另一种方法,是否跨立)
{
if(maxx(a)<minx(b)||maxy(a)<miny(b)) return false;
if(maxx(b)<minx(a)||maxy(b)<miny(a)) return false;
double s1=(a.t-a.s)^(b.s-a.s),s2=(a.t-a.s)^(b.t-a.s);
double s3=(b.t-b.s)^(a.s-b.s),s4=(b.t-b.s)^(a.t-b.s);
return dcmp(s1)*dcmp(s2)<=0&&dcmp(s3)*dcmp(s4)<=0;//a的端点在b的两侧且b的端点在a的两侧
}
inline double s_t(vec a,vec b,vec c){return dabs((b-a)^(c-a))/2;}//已知三点求三角形面积
/*多边形*/
struct pol
{
vector<vec> pt;
inline vec& operator [](int x){return pt[x];}
inline int ne(int x){return (x<pt.size()-1)?x+1:0;}
inline void insert(vec p){pt.push_back(p);}
inline void clear(){pt.clear();}
inline int include(vec p)//点在多边形外:0,在多边形内:1,在多边形边上:2
{
int cnt=0;
for(int i=0;i<pt.size();i++)//射线法判断,射线方向为x轴正方向
{
vec s=pt[i],t=pt[ne(i)];line l=line(s,t);
if(pd_px(p,l)) return 2;
if(dcmp(p.y-miny(l))>=0&&dcmp(maxy(l)-p.y)>0)
if(dcmp(s.x+((p.y-s.y)/(t.y-s.y)*(t.x-s.x))-p.x)>0) cnt++;
}
return cnt&1;//偶数个交点则在多边形外,奇数个交点则在多边形内
}
inline double s_p()//多边形面积
{
double ans=0;
for(int i=1;i<pt.size()-1;i++) ans+=(pt[i]-pt[0])^(pt[ne(i)]-pt[0]);
return dabs(ans)/2;
}
inline double c_p()//多边形周长
{
double ans=0;
for(int i=0;i<pt.size();i++) ans+=dis(pt[i],pt[ne(i)]);
return ans;
}
inline bool pd_l(vec x,vec l,vec r){return dcmp((l-x)^(r-x))<=0;}//xl是否在xr的左侧
inline int include_(vec p)//二分法判断点是否在多边形内
{
int n=pt.size();
if(!pd_l(pt[0],p,pt[1])) return 0;
if(!pd_l(pt[0],pt[n-1],p)) return 0;
if(pd_px(p,line(pt[0],pt[1]))) return 2;
if(pd_px(p,line(pt[0],pt[n-1]))) return 2;
int l=1,r=n-2,ans=1,mid;
while(l<=r)//二分找到最接近线(pt[0],p)的(pt[0],pt[ans])
{
mid=l+r>>1;
if(!pd_l(pt[0],pt[mid],p)) l=mid+1,ans=mid;
else r=mid-1;
}
if(!pd_l(pt[ans],p,pt[ne(ans)])) return 0;
if(pd_px(p,line(pt[ans],pt[ne(ans)]))) return 2;
return 1;
}
};
/*凸包*/
inline void andrew(pol &p)
{
vector<vec>q(p.pt.size()<<1);int top=0,n=p.pt.size();
sort(p.pt.begin(),p.pt.end(),cmp_vec),q[top]=p[0];
for(int i=1;i<n;i++)
{
while(top&&dcmp((q[top-1]-q[top])^(q[top-1]-p[i]))<=0) top--;
q[++top]=p[i];
}
int tot=top;
for(int i=n-2;i>=0;i--)
{
while(top>tot&&dcmp((q[top-1]-q[top])^(q[top-1]-p[i]))<=0) top--;
q[++top]=p[i];
}
if(n>1) top--;
p.clear();
for(int i=0;i<=top;i++) p.insert(q[i]);
}
/*旋转卡壳*/
inline double diam(pol p)
{
int n=p.pt.size();double ans=0;
for(int i=0,j=1;i<n;i++)
{
for(;;j=p.ne(j)) if(dcmp(s_t(p[j],p[i],p[p.ne(i)])-s_t(p[p.ne(j)],p[i],p[p.ne(i)]))>=0) break;
ans=max(ans,max(dis(p[j],p[i]),dis(p[j],p[p.ne(i)])));
}
return ans;
}
int main()
{
double x1,x2,x3,y1,y2,y3;
scanf("%lf%lf%lf%lf%lf%lf",&x1,&y1,&x2,&y2,&x3,&y3);
printf("%.2lf",s_t(vec(x1,y1),vec(x2,y2),vec(x3,y3)));
}
虽然有很多函数没有用到,但是多打打锻炼码力和熟悉度还是很不错的。(确信
N
思路
略。(编不下去了—)
AC code
#include<bits/stdc++.h>
using namespace std;
int a,b;
int main()
{
scanf("%d%d",&a,&b);
printf("%d %d",a/b,a%b);
}
O
思路
哇哇,线段长度,显然也是计算几何,害怕大家审美疲劳,这里放另一个模板。
AC code
//计算几何小板子
#include<bits/stdc++.h>
using namespace std;
const int eps=1e-8;
const double Pi=acos(-1.0);
int dcmp(double x){return (x<-eps)?-1:(x>eps?1:0);}//小于0返回-1 大于0返回1 等于0返回0
double Abs(double x){return x*dcmp(x);}
//Computer Graphics
namespace CG
{
struct pt{double x,y;pt(double tx=0,double ty=0){x=tx,y=ty;}};
inline bool cmpx(const pt &a,const pt &b){return (a.x!=b.x)?a.x<b.x:a.y<b.y;}//以x为第一关键字比较
typedef pt vec;//vec:向量,可以直接用点表示
inline double Len(const vec &a){return sqrt(a.x*a.x+a.y*a.y);}//向量的模长
inline double angle(const vec &a){return atan2(a.y,a.x);}//向量与x轴的夹角
inline vec operator +(const vec &a,const vec&b){return vec(a.x+b.x,a.y+b.y);}//向量加法
inline vec operator -(const vec &a,const vec&b){return vec(a.x-b.x,a.y-b.y);}//向量减法
inline vec operator *(const vec &a,const double b){return vec(a.x*b,a.y*b);}//向量数量积(重载参数)
inline vec operator /(const vec &a,const double b){return vec(a.x/b,a.y/b);}//向量数量积的逆运算(除法)(重载参数)
inline double operator *(const vec &a,const vec&b){return a.x*b.x+a.y*b.y;}//向量点积(重载参数)
inline double operator ^(const vec &a,const vec&b){return a.x*b.y-a.y*b.x;}//向量叉积-忽略了方向,只保留正负(重载参数)
inline vec rotate(vec a,double theta)//将向量绕原点逆时针旋转角theta的弧度
{return vec(a.x*cos(theta)-a.y*sin(theta),a.x*sin(theta)+a.y*cos(theta));}
inline vec rotate_90(vec a){return vec(a.y,-a.x);}//向量绕原点逆时针旋转90度
inline pt rotate_p(pt a,pt b,double theta){return rotate(a-b,theta)+b;}//将点a绕点b旋转theta 实现方法相当于平移了坐标系
//命名技巧:点P(point),线段S(segment),射线R(ray),直线L(line)
struct line{pt s,t;line(pt ts=pt(0,0),pt tt=pt(0,0)){s=ts,t=tt;}};//两端点表示一条线段
inline double maxx(const line &L){return max(L.s.x,L.t.x);}
inline double minx(const line &L){return min(L.s.x,L.t.x);}
inline double maxy(const line &L){return max(L.s.y,L.t.y);}
inline double miny(const line &L){return min(L.s.y,L.t.y);}
inline double angle(const line &L){return angle(L.t-L.s);}//直线与x轴的夹角(重载参数)
inline bool operator <(const line &a,const line &b)//判断b在a的逆时针方向(b与x轴的夹角更大)则返回真
{
//没有明白为什么要先判断角再用叉积判断 而且原博客似乎写错了
double a1=angle(a.t-a.s),a2=angle(b.t-b.s);
if(dcmp(a2-a1)!=0) return dcmp(a2-a1)>0;
else return dcmp((a.t-a.s)^(b.t-b.s));//似乎这里原博客错了
}
inline bool operator ==(pt a,pt b){return (!dcmp(a.x-b.x))&&(dcmp(a.y-b.y));}//判断两点是否重合
inline double dis_PP(pt a,pt b){return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y));}//两点距离
inline bool judge_PL(pt a,line b){return !dcmp((a-b.s)^(b.t-b.s));}//判断点是否在直线上(叉积为0)
inline bool judge_PS(pt a,line b){return (!dcmp((a-b.s)^(b.t-b.s)))&&(dcmp((a-b.s)*(a-b.t))<=0);}//判断点是否在线段上
inline pt Footpoint(pt a,line b)//点A在直线ST上的垂足
{
vec x=a-b.s,y=a-b.t,z=b.t-b.s;
double s1=x*z,s2=-1.0*(y*z);//AS、AT在ST上的投影 | 正负必须这么处理,以解决垂足不在线段b上的情况
return b.s+z*(s1/(s1+s2));//一次解决垂足在S左侧、线段b上、T右侧三种情况
}
inline pt mirror(pt a,line b){return a+(Footpoint(a,b)-a)*2.0;}//点a关于直线b的对称点
inline double dis_PL(pt a,line b){return Abs((a-b.s)^(a-b.t))/Len(b.t-b.s);}//点到直线的距离:面积除以底边长
inline double dis_PS(pt a,line b)//点到线段的距离
{
vec x=a-b.s,y=a-b.t,z=b.t-b.s;
if(dcmp(x*z)<0) return Len(x);//垂足在左端点左侧,a离左端点最近
if(dcmp(y*z)>0) return Len(y);//垂足在右端点右侧,a离右端点最近
return dis_PL(a,b);//垂足在线段上
}
inline pt point_PS(pt a,line b)//点a在线段b上距离最近的点
{
vec x=a-b.s,y=a-b.t,z=b.t-b.s;
if(dcmp(x*z)<0) return b.s;//垂足在左端点左侧,a离左端点最近
if(dcmp(y*z)>0) return b.t;//垂足在右端点右侧,a离右端点最近
return Footpoint(a,b);//垂足在线段上,垂足距离最近
}
inline pt cross_LL(line a,line b)//直线的交点
{
vec x=a.t-a.s,y=b.t-b.s,z=a.s-b.s;
return a.s+x*((y^z)/(x^y));//按照面积比找到交点在a上的位置,此处需要画图理解
}
inline bool judge_cross_SL(line a,line b)//判断线段a和直线b是否相交
{
if(!dcmp((a.t-a.s)^(b.t-b.s))) return false;//线段所在直线平行
return judge_PS(cross_LL(a,b),a);//两直线交点在a上
}
inline bool judge_cross_LL(line a,line b)//判断线段a和线段b是否相交
{
return judge_cross_SL(a,b)&&judge_cross_SL(b,a);//线段a与直线b相交且线段b与直线a相交 | 原博客判断方法有些复杂
}
}
using namespace CG;
int main()
{
pt A,B;
scanf("%lf%lf%lf%lf",&A.x,&A.y,&B.x,&B.y);
printf("%.3lf",dis_PP(A,B));
return 0;
}
P
思路
甲流好可怕qwq。
AC code
#include<bits/stdc++.h>
using namespace std;
int a,b;
int main()
{
scanf("%d%d",&a,&b),printf("%.3lf",100.0*b/a),cout<<"%";
}
Q
思路
略略略。
AC code
#include<bits/stdc++.h>
using namespace std;
double n;
int main()
{
scanf("%lf",&n),printf("%.5lf",5.0*(n-32)/9);
}
R
思路
怎么还有⚪啊。
AC code
#include<bits/stdc++.h>
using namespace std;
const double pi=3.14;
double n;
int main()
{
scanf("%lf",&n),printf("%.2lf",4.0/3*pi*n*n*n);
}