抽了小半天空做了一下这套题…
A.
简单坑题,由于英文不好被题意gank了,判断(a+b+c+d)*2是否大于等于n+1…
#include<bits/stdc++.h>
#define LiangJiaJun main
using namespace std;
int T,n,a,b,c,d;
int w33ha(){
scanf("%d%d%d%d%d",&n,&a,&b,&c,&d);
if(((a+b+c+d)<<1)<n+1)puts("No");
else puts("Yes");
return 0;
}
int LiangJiaJun(){
scanf("%d",&T);
while(T--)w33ha();
return 0;
}
B.
有T组询问,每次询问两个数字M和D,求问能装下质量为M,密度为D的液体的容器的最小表面积。
很显然这个容器是个球体,我们先求出液体的体积V,这个可以通过密度公式
D
=
M
/
V
D = M/V
D=M/V来求。
然后球体体积已知之后我们求出球体半径
r
(
V
=
4
/
3
∗
p
i
∗
(
r
3
)
)
r(V = 4/3*pi*(r^3))
r(V=4/3∗pi∗(r3)),然后球体表面积就是
4
∗
p
i
∗
(
r
2
)
4* pi *(r^2)
4∗pi∗(r2)
tips: cbrt(x)
是求
x
x
x的立方根的函数。
#include<bits/stdc++.h>
#define LiangJiaJun main
#define pi acos(-1)
#define ll long long
using namespace std;
int T;
ll m,d;
int w33ha(int CASE){
scanf("%lld%lld",&m,&d);
double V=1.0*m/(1.0*d);
double r=cbrt(V*3/4/pi);
printf("Case %d: %.4lf\n",CASE,4*pi*r*r);
return 0;
}
int LiangJiaJun(){
scanf("%d",&T);
for(int i=1;i<=T;i++)w33ha(i);
return 0;
}
C.
给出半圆ADBCA的半径
r
r
r,求图中阴影部分面积。
瞎算算就知道是 ( r 2 ) / 4 (r^2)/4 (r2)/4
#include<bits/stdc++.h>
#define LiangJiaJun main
#define pi acos(-1)
using namespace std;
double r;
int w33ha(int CASE){
scanf("%lf",&r);
printf("Case %d: %.4lf\n",CASE,(r*r)/4.0);
return 0;
}
int LiangJiaJun(){
int T;
scanf("%d",&T);
for(int i=1;i<=T;i++)w33ha(i);
return 0;
}
D.
T
(
T
<
=
10000
)
T(T<=10000)
T(T<=10000)次询问,每组询问询问一个
N
(
N
<
=
1
0
9
)
N(N<=10^9)
N(N<=109),要求输出第
N
N
N小的长度为奇数的回文数字。
限定:第一小的回文数字是
1
1
1
这道题可以先预处理长度为x的回文数字的数量,这个可以通过递推解决(长度+1,数量*10)。
然后先确定当前询问的N的对应的回文数字的位数,然后从第一位向中间慢慢统计答案即可。
#include<bits/stdc++.h>
#define LiangJiaJun main
#define pi acos(-1)
#define ll long long
using namespace std;
ll sum[104];
int n,ans[104];
int w33ha(int CASE){
scanf("%d",&n);
int np=1;
while(n>sum[np]){
n-=sum[np];
np+=2;
}
int half=np/2+1;
for(int i=1;i<=half;i++){
int now=0;
if(i==1)now++;
ll civ=1;
for(int j=i+1;j<=half;j++)civ*=10;
while(n>civ){
++now;
n-=civ;
}
ans[i]=now;
}
printf("Case %d: ",CASE);
for(int i=1;i<=half;i++)printf("%d",ans[i]);
for(int i=half-1;i;i--)printf("%d",ans[i]);
puts("");
return 0;
}
int prework(){
sum[1]=9;
for(int i=3;sum[i-2]<=1000000000LL;i+=2){
int pre=i-2;
sum[i]=sum[pre]*10;
}
return 0;
}
int LiangJiaJun(){
prework();
int T;scanf("%d",&T);
for(int i=1;i<=T;i++)w33ha(i);
return 0;
}
E.
给定一个
d
(
0
<
=
d
<
=
60
)
d(0<=d<=60)
d(0<=d<=60)一个
x
(
0
<
=
x
<
=
1
0
18
)
x(0<=x<=10^{18})
x(0<=x<=1018),你位于一个数轴上,这个数周只有非负整数。刚开始你位于数轴的
0
0
0位置,每次你可以向正方向或者负方向跳
2
d
2^d
2d的长度,每跳一次,
d
d
d的值减少
1
1
1,当
d
d
d小于
0
0
0的时候,你就不能跳了。询问给定的
d
d
d能否在几次跳跃之后到达
x
x
x点。如果可以,则输出YES和至少跳几次,否则输出NO。
我们可以知道每个数字都是可以被分解成若干个不同2的幂的加和。首先 d + 1 d+1 d+1如果大于等于x二进制分解后的长度cnt,则一定有解,否则无解。然后接下来求至少跳几次,从高位到低位,如果 d + 1 > = c n t d+1>=cnt d+1>=cnt那么这个是一定要跳的(第一次往正方向,其余次都是负方向),之后就是如果当前位置开始往地位都已经没有 1 1 1了,那么就停止跳跃,否则继续跳。注意特判 x = = 0 x==0 x==0的情况。
#include<bits/stdc++.h>
#define LiangJiaJun main
#define pi acos(-1)
#define ll long long
using namespace std;
ll d;
ll x,poc[74],soc[74];
int w33ha(int CASE){
scanf("%lld%lld",&d,&x);
if(x==0){
return printf("Case %d: YES 0\n",CASE),0;
}
int cnt=0;
while(x){
poc[++cnt]=(x&1);
x>>=1;
}
d++;
soc[0]=0;
for(int i=1;i<=cnt;i++)soc[i]=soc[i-1]+poc[i];
bool flag=0;
if(d<cnt)flag=1;
int ans=0;
while(d>=cnt){
ans++;
d--;
}
cnt--;
while(cnt){
if(poc[cnt]==1){
ans++;
}
else{
if(soc[cnt]==0)break;
else ans++;
}
cnt--;
}
if(flag)printf("Case %d: NO\n",CASE);
else printf("Case %d: YES %d\n",CASE,ans);
return 0;
}
int LiangJiaJun(){
int T;scanf("%d",&T);
for(int i=1;i<=T;i++)w33ha(i);
return 0;
}
F.
题意:
给了一个生成图的方法:给定一个
n
n
n,先创建出所有他的因数
(
大
于
1
)
(大于1)
(大于1)的节点。然后对于每个节点,把它和它的因数之间连边。
有
T
T
T组询问,每次询问一个
n
n
n,问从
1
1
1~
n
n
n中随机选出一个数字
i
i
i,使得它生成的图是一棵树的概率(用分数表示)。
通过性质可以知道,如果一个数字质因数分解的结果中有超过2个质数,那么这个数字生成的图就不是树。那么只要预处理小于等于1000000的数字中质因数个数小于等于2的数字有几个即可,查询就是log级别(指求最大公因数)的了。
#include<bits/stdc++.h>
#define LiangJiaJun main
#define pi acos(-1)
#define ll long long
using namespace std;
int t[1000004];
int pri[1000004];
int cnt,cnt1000,ans[1000004];
int monk(int x){
int now=x,cp=1;
while(cp<=cnt1000&&pri[cp]<=now&&now>1){
if(now%pri[cp]==0){
now/=pri[cp];
if(t[now])return 0;
else return 1;
}
cp++;
}
return 1;
}
int prework(){
t[1]=1;t[0]=1;
cnt=0;
for(int i=1;i<=1000000;i++){
if(!t[i]){
for(int j=i<<1;j<=1000000;j+=i)t[j]=1;
}
}
for(int i=1;i<=1000000;i++){
if(!t[i]){
pri[++cnt]=i;
ans[i]=1;
if(1LL*i*i<=1000000)ans[i*i]=1;
}
}
cnt1000=cnt;
while(pri[cnt1000]>1000)cnt1000--;
ans[1]=1;
for(int i=2;i<=1000000;i++){
if(ans[i])continue;
ans[i]=monk(i);
}
for(int i=1;i<=1000000;i++)ans[i]+=ans[i-1];
}
int n;
int w33ha(int CASE){
scanf("%d",&n);
int d=__gcd(n,ans[n]);
printf("Case %d: %d/%d\n",CASE,ans[n]/d,n/d);
return 0;
}
int LiangJiaJun(){
prework();
int T;scanf("%d",&T);
for(int i=1;i<=T;i++)w33ha(i);
return 0;
}
G.
统计一个字符串(长度<=
1
0
5
10^5
105)的所有子串的价值之和对
1
0
9
+
7
10^9+7
109+7取模的结果。
一个串的价值被定义为:
"它的所有字符的ascii码值 乘以 串的长度"
我们可以考虑对于一个位置上的字符来说,它需要乘以多少。
对于处于
i
i
i位置的字符,能够覆盖它的子串的起点显然位于
1
1
1到
i
i
i,而且对于不同的起点,子串的数量相同,都是
(
n
−
i
+
1
)
(n-i+1)
(n−i+1)。而且对于以
j
j
j为起点的子串,能够覆盖
i
i
i的所有子串的长度之和为
(
l
+
i
−
2
∗
(
j
−
1
)
)
∗
(
l
−
i
+
1
)
/
2
(l+i-2*(j-1))*(l-i+1)/2
(l+i−2∗(j−1))∗(l−i+1)/2然后这个是一个以
(
l
−
i
+
1
)
(l-i+1)
(l−i+1)为差值的等差数列,然后对于每个
i
i
i来说就可以求了它要乘多少了。记得long long
#include<bits/stdc++.h>
#define LiangJiaJun main
#define pi acos(-1)
#define ll long long
#define MOD 1000000007LL
using namespace std;
char s[100004];
int w33ha(int CASE){
int l;
scanf("%d",&l);
scanf("%s",s+1);
ll ans=0;
for(int i=1;i<=l;i++){
ll bg=1LL*(l+i)*(l-i+1)>>1;
ll ed=1LL*(l-i+2)*(l-i+1)>>1;
ll cnt=1LL*(bg+ed)*i>>1;
ans=(ans+((ll)s[i])*cnt)%MOD;
}
printf("Case %d: %lld\n",CASE,ans);
return 0;
}
int LiangJiaJun(){
int T;scanf("%d",&T);
for(int i=1;i<=T;i++)w33ha(i);
return 0;
}
H.
给一个字符串(长度
<
=
6000
<=6000
<=6000),和
q
q
q组询问,询问一个区间和一个数字maxvalue,对这个区间进行一个操作,区间的价值设定为:区间中每个字符和它以这个区间的中心的对称字符的ascii码的差的绝对值之和。如果区间价值
>
m
a
x
v
a
l
u
e
>maxvalue
>maxvalue,则去掉这个区间的两端的元素,直到区间价值
<
=
m
a
x
v
a
l
u
e
<=maxvalue
<=maxvalue最后输出满足区间价值
<
=
m
a
x
v
a
l
u
e
<=maxvalue
<=maxvalue的最长的串的长度。
预处理之后对于每个询问二分删除元素的个数即可。细节有点多,注意。
#include<bits/stdc++.h>
#define LiangJiaJun main
#define pi acos(-1)
#define ll long long
#define MOD 1000000007LL
#define INF 1999122700
using namespace std;
char s[6004];
int n;
int mp[6004][6004];
int prework(){
for(int i=1;i<=n;i++){
for(int l=i,r=i;l>0&&r<=n;l--,r++){
mp[l][r]=mp[l+1][r-1]+abs(0+s[l]-s[r]);
}
for(int l=i,r=i+1;l>0&&r<=n;l--,r++){
mp[l][r]=mp[l+1][r-1]+abs(0+s[l]-s[r]);
}
}
return 0;
}
int query(int a,int b,int val){
int ans=INF,l=0,r=b-a,mid;
while(l<=r){
mid=(l+r)>>1;
int cl=a+mid,cr=b-mid,calc;
if(cl>=cr)calc=0;
else calc=mp[cl][cr];
if(calc<=val){
ans=mid;
r=mid-1;
}
else{
l=mid+1;
}
}
return b-a+1-(ans<<1);
}
int w33ha(int CASE){
scanf("%s",s+1);
n=strlen(s+1);
prework();
int q;scanf("%d",&q);
while(q--){
int a,b,val;
scanf("%d%d%d",&a,&b,&val);
printf("%d\n",query(a,b,val));
}
return 0;
}
int LiangJiaJun(){
memset(mp,0,sizeof(mp));
int T;scanf("%d",&T);
for(int i=1;i<=T;i++)w33ha(i);
return 0;
}
I.
咕咕咕
J.
咕咕咕