做题记录(8月)
test 807
dice
题目大意
构造
solution
注意到
对于一个 64 进制的数,如果每一位都是
具体构造方法:
6个数为:
cut
题目大意
定义
solution
发现权值最大为21,
hamilton
solution
每个点入出度都为1,可以使用最大流
建图方法:
如果最后最大流等于
否则,就说明无解。
test 809
genshin
题目大意
有
solution
对于一个人能听到的范围为
花费可以表示为
很明显它是一个单峰函数,线性函数可以使用二分,单峰函数可以考虑使用三分,枚举答案再
while(l<=r) {
lc=l+(r-l)/3;
rc=r-(r-l)/3;
int lans=work(lc),rans=work(rc);
if(lans<=rans) {
ans=min(lans,ans);
r=rc-1;
} else {
ans=min(ans,rans);
l=lc+1;
}
}
arknights
solution
题目规定一个斜线最多出现一个棋子,但并不是很好处理,我么可以我们取出其黑色部分,然后旋转90度。
可以考虑
arena
观察条件
从
test 0812
网格行走(path)
题意
给定一个
solution
如果我们想要
考虑二分
lock
题意
给一个有四个拨圈的锁,这种密码锁被解锁当且仅当拨圈每四个对应位置之和相等。判断密码锁是否能打开
solution
虽然有四个拨圈,但其实只需要转动三个拨圈即可。
令
剩下三个拨圈的和为
test 0814
C. 你所热爱的就是你的生活(ll.cpp)
solution
直接爆搜肯定会超时,靠虑折半搜索,把区间
test 0816
数学(math)
题意
<img src="https://s1.ax1x.com/2023/08/15/pPQnScd.png" alt="image-20230815171924641" style="zoom:50%;" />
子弹从点
你认为,若在射线
现在我们需要你对于每一组询问求出 P 点坐标。
solution
有是2一道纯数学题,没有用到任何三角函数,单纯几何知识
如图构造一个圆EAB,此时∠AEB最大
不难发现
求出
while(t--){
double xa,xb,ya,yb,xm,ym;
cin>>xa>>ya>>xb>>yb>>xm>>ym;
double s=sqrt(xa*xb);
double t=sqrt(xm*xm+ym*ym);
double k=s/t;
cout<<fixed<<setprecision(7)<<xm*k<<" "<<ym*k<<endl;
}
test 0818
手语的(gnsi)
题意
给你一个平面。
给你三个正交矩形和一个点,问是否存在一个三角形,使得该三角形的三个顶点分别在三个正交矩形内,且该三角形的重心为给定点。
正交矩形:四条边都平行于坐标轴的矩形。
solution
众所周知,在重心为三角形三条中线的交点,在平面直角坐标系中,
while(t--){
minx=miny=maxx=maxy=0;
for(int i=1;i<=3;i++){
cin>>_x1[i]>>_x2[i]>>_y1[i]>>_y2[i];
minx=minx+min(_x1[i],_x2[i]);
maxx=maxx+max(_x1[i],_x2[i]);
miny=miny+min(_y1[i],_y2[i]);
maxy=maxy+max(_y1[i],_y2[i]);
}
int x,y;
cin>>x>>y;
x*=3;y*=3;
if(x>=minx&&x<=maxx&&y>=miny&&y<=maxy)
cout<<"heihei"<<endl;
else cout<<"yiyandingzhen"<<endl;
}
A. 序列(sequence)
solution
从
而小于
我们可以记
最后在用树状数组维护,复杂度可以做到
test 0819
序列II(quencese)
题意
你现在有一序列
设末尾的数是
如此进行
solution
设
时间复杂度
我们直接枚举第三个元素
时间复杂度
int f(int i) {
if(g[i] != 0) return g[i];
if(i == 1) return 1;
int s = 0;
for(int j = 1; j <= sqrt(i); j++) s = (s + f(j)) % mod;
return g[i] = s;
}
int get2(int n) {
int num = sqrt(n);
return sum[num];
}
int get(int n) {
int p = sqrt(n);
int q = sqrt(p);
int ans = 0;
q--;
for(int i = 1; i <= q; i++)
ans = (ans + get2(i * i) * (2 * i + 1) % mod) % mod;
q++;
ans = (ans + (p - q * q + 1) * get2(q * q) % mod) % mod;
return ans;
}
signed main() {
cin >> T;
for(int i = 1; i <= 100000; i++) {
sum[i] = sum[i - 1] + f(i);
}
while(T--) {
cin >> n;
cout << get(n) << endl;
}
数学(math)
题意
给定
solution
一道纯数学题 ,要用韦达定理来证明
韦达定理:
多个未知数的高次方程不难想到用主元法,我们以
利用韦达定理易知
所以一组解为
test 0822
A. 压轴题(hard)
水题,暴力打表后发现答案都是
B. 极端题(extreme)
题意
给定一个数列,每次可以把一个数分拆成两个正整数,求它的每个子数组变成不降数列的最小操作数之和
solution
test 0823
A. 简化题面 (statement)
题意
对一个数进行操作把这个数字按照不降序进行排列,之后把所有的前导零去掉。 对
看见题目里面的区间
void dfs(int u,int left){
if(u==9){
nums[u]=left;
if(check(len,true,true)){
ans++;
}
return;
}
for(int i=0;i<=left;i++){
nums[u]=i;
dfs(u+1,left-i);
}
}
搜索出了答案我们可以考虑如何做到快速判断答案的是否正确。我采用数位
B. 题面不长(nothing)
题意
给定
n,k 和m 。对于每个大小在[1, n] 中的x ,求每个元素大小在[1, n] 中,平均数为x 且相同元素不超过k 个的可重集的数量,对m 取模。 > >1\le n, k\le100 ,m 为质数。
solution
如果集合中的平均数为
要让和为
令
可以用前缀和优化的多重背包求出
时间复杂度
C. 题面很短 (short)
题意
对于字符串
给定字符串
solution
签到题,每次二分后进行比对就行,数据很水
string fz(string a) {
int cnt=0;
string b="";
for(int i=a.size()-1; i>=0; i--) {
b+=a[i];
}
return b;
}