【题解】牛客小白月赛58
【题解】牛客小白月赛58 (By Christophe)
A-双子爆破者
题目链接
A-双子爆破者题目分析
签到题,根据题目给出的公式输出答案即可.
代码
// Problem: 双子爆破者
// Contest: NowCoder
// URL: https://ac.nowcoder.com/acm/contest/41173/A
// Memory Limit: 524288 MB
// Time Limit: 2000 ms
//
// Powered by CP Editor (https://cpeditor.org)
#include<bits/stdc++.h>
using namespace std;
int T;
double m,M,v;
int main(){
cin>>T;
while(T--){
cin>>M>>m>>v;
cout<<(m*v)/(M-m)<<endl;
}
return 0;
}B-牛原子
题目链接
B-牛原子题目分析
模拟题,根据题意运用前缀和 + 排序即可.
代码
// Problem: 牛原子
// Contest: NowCoder
// URL: https://ac.nowcoder.com/acm/contest/41173/B
// Memory Limit: 524288 MB
// Time Limit: 2000 ms
//
// Powered by CP Editor (https://cpeditor.org)
#include<bits/stdc++.h>
using namespace std;
#define lowbit(x) ((x)&(-(x)))
#define lg2(x) ((int)(__lg(x)/__lg(2)))
typedef long long LL;
typedef unsigned long long ull;
const int N=1e6+10,INF=2e9+10;
inline int read(){
int ret=0,f=1;
char ch=getchar();
while(ch<'0'||ch>'9'){ if(ch=='-') f=-f; ch=getchar(); }
while(ch>='0'&&ch<='9') ret=ret*10+ch-'0',ch=getchar();
return ret*f;
}
inline void write(int x){
if(x<0){ putchar('-'); x=-x; }
if(x>9) write(x/10);
putchar(x%10+'0');
}
int hs1[20]={0,1,2,2,3,3,4,3,4,5,4,5,6,4,5,6,7,5,6,7};//题目中的第一项系数
int hs2[20]={0,2,2,6,2,6,2,10,6,2,10,6,2,14,10,6,2,14,10,6};//对应的 s/p/d/f ,以填满所需的电子数为代表
int T,n,s[20],tp;
struct Node{
int cg;//电子亚层数
int spdf;//s or p or d or f
int ct;//电子数
bool operator<(const Node &B)const{
return cg<B.cg||(cg==B.cg&&spdf<B.spdf);
}
}st[N];
char to(int x){//s->2 p->6 d->10 f->14
if(x==2) return 's';
if(x==6) return 'p';
if(x==10) return 'd';
return 'f';
}
void update(int i,int k){
st[++tp]={hs1[i],hs2[i],k};
}
int main(){
T=read();
for(int i=1;i<=19;++i) s[i]=s[i-1]+hs2[i];
while(T--){
tp=0,n=read();
int p=upper_bound(s+1,s+19+1,n)-s;
for(int i=1;i<=p-1;++i) update(i,hs2[i]);
if(n>s[p-1]) update(p,n-s[p-1]);
sort(st+1,st+tp+1);
for(int i=1;i<=tp;++i){
write(st[i].cg);
putchar(to(st[i].spdf));
write(st[i].ct);
putchar(' ');
}
puts("");
}
return 0;
}C-牛牛
题目链接
C-牛牛题目分析
考虑将选
个转化为选
个,
记
张卡牌总和为
,
选的两个数为
,
,
则有
,
也即
,
枚举
,在模意义下寻找
即可,可以使用
.
不过由于值域是
而不是
,这里的取模需要特殊处理一下
.
- 代码
// Problem: 牛牛
// Contest: NowCoder
// URL: https://ac.nowcoder.com/acm/contest/41173/C
// Memory Limit: 524288 MB
// Time Limit: 2000 ms
//
// Powered by CP Editor (https://cpeditor.org)
#include<bits/stdc++.h>
using namespace std;
#define int long long
#define lowbit(x) ((x)&(-(x)))
#define lg2(x) ((int)(__lg(x)/__lg(2)))
typedef long long LL;
typedef unsigned long long ull;
const int N=1e6+10,INF=2e9+10;
inline int read(){
int ret=0,f=1;
char ch=getchar();
while(ch<'0'||ch>'9'){ if(ch=='-') f=-f; ch=getchar(); }
while(ch>='0'&&ch<='9') ret=ret*10+ch-'0',ch=getchar();
return ret*f;
}
inline void write(int x){
if(x<0){ putchar('-'); x=-x; }
if(x>9) write(x/10);
putchar(x%10+'0');
}
int T,n,m,s,s0,a[N];
bool flag;
inline int mod(int x,int m){
if(x%m!=0) return x%m;
return m;
}
signed main(){
T=read();
while(T--){
n=read(),m=read(),s=0,flag=0;
for(int i=1;i<=n;++i) a[i]=read(),s+=a[i];
map<int,int> mp;
mp[a[1]]=1;
for(int j=2;j<=n;++j){
if(mp.find(mod(s-a[j],m))!=mp.end()){
int i=mp[(s-a[j])%m];
flag=1;
s0=a[i]+a[j];
break;
}
mp[a[j]]=j;
}
if(flag) write(mod(s0,m));
else write(0);
puts("");
}
return 0;
}D-数学考试
题目链接
D-数学考试题目分析
入门
题.
定义
表示做完第
份作业后,压力指标为
时可积累的最大经验,
考虑如何使得压力指标在做完第
份作业后变为
,
根据题意,
要么做完
份时压力
;
要么
是
,即
;
要么
是
,即
;
故
.
注意
,转移时特判一下就好.
由于初始的压力值没有确定,不妨都赋上初值(容易发现是
),以便于后继状态可以从前面的任意一个状态转移过来,最终的答案也即是考虑所有可能的初值的正确答案.
至于空间限制,滚动数组滚一下就好了.
- 代码
// Problem: 数学考试
// Contest: NowCoder
// URL: https://ac.nowcoder.com/acm/contest/41173/D
// Memory Limit: 131072 MB
// Time Limit: 2000 ms
//
// Powered by CP Editor (https://cpeditor.org)
#include<bits/stdc++.h>
using namespace std;
#define int long long
#define lowbit(x) ((x)&(-(x)))
#define lg2(x) ((int)(__lg(x)/__lg(2)))
typedef long long LL;
typedef unsigned long long ull;
const int N=1e6+10,INF=2e10+10,MIN=-INF;
inline int read(){
int ret=0,f=1;
char ch=getchar();
while(ch<'0'||ch>'9'){ if(ch=='-') f=-f; ch=getchar(); }
while(ch>='0'&&ch<='9') ret=ret*10+ch-'0',ch=getchar();
return ret*f;
}
inline void write(int x){
if(x<0){ putchar('-'); x=-x; }
if(x>9) write(x/10);
putchar(x%10+'0');
}
int n,k,a[N],b[N],q[N],w[N],dp[2][N];
int get(int x,int i){
return x<=b[i]?a[i]*x:0;
}
signed main(){
n=read(),k=read();
for(int i=1;i<=n;++i){
a[i]=read(),b[i]=read();
q[i]=read(),w[i]=read();
}
for(int i=0;i<=1;++i){
for(int j=0;j<=k;++j){
if(i==0) dp[i][j]=0;
else dp[i][j]=MIN;
}
}
for(int i=1;i<=n;++i){
for(int j=0;j<=k;++j){
int tmp=MIN;
if(dp[(i-1)&1][j]!=MIN) tmp=max(tmp,dp[(i-1)&1][j]+get(j,i));
if(j-q[i]>=0&&dp[(i-1)&1][j-q[i]]!=MIN) tmp=max(tmp,dp[(i-1)&1][j-q[i]]+get(j-q[i],i));
if(j+w[i]<=k&&dp[(i-1)&1][j+w[i]]!=MIN) tmp=max(tmp,dp[(i-1)&1][j+w[i]]+get(j+w[i],i));
dp[i&1][j]=tmp;
}
}
int cnt=MIN;
for(int j=0;j<=k;++j) cnt=max(cnt,dp[n&1][j]);
write(cnt);
return 0;
}E-法力无边
题目链接
E-法力无边题目分析
考虑按位统计答案,
在二进制下我们不进行进位,
对于第
位的答案
,
对答案贡献为
.
按位计算后,问题就简化为每一个数
只可能是
或
的情况,
我们在这个条件下对同或的性质进行研究,
如果能
计算出
,
这一题就解决了.
根据真值表,我们发现
,即
对于同或的结果没有影响,
那么同或的结果就只和参与运算的
的个数有关.
进一步地分析可知:
如果参与运算的
为奇数个,同或的结果为
;
如果参与运算的
为偶数个,同或的结果为
;
于是,
我们记
表示以
为结尾的所有子串中同或和为
的个数,
相应地
表示以
为结尾的所有子串中同或和为
的个数,
那么以
为结尾的所有子串对
的贡献就是
.
考虑转移,
(i). 如果
为
:
那么阶段
的答案与
的答案的唯一差异在于,
以
为结尾的所有同或和为
的子串中,
多出了一个长度为
的子串
,
也即
本身,
因此转移为
;
(ii). 如果
为
:
(1). 阶段
的答案中同或和为
的所有子串,
在消去结尾的
之后,
就是在
阶段中同或和为
的那些子串,
因此转移为
;
(2). 阶段
的答案中同或和为
的所有子串(除了子串
),
在消去结尾的
之后,
就是在
阶段中同或和为
的那些子串,
由于还多了一个子串
,
因此转移为
.
代码
// Problem: 法力无边
// Contest: NowCoder
// URL: https://ac.nowcoder.com/acm/contest/41173/E
// Memory Limit: 524288 MB
// Time Limit: 2000 ms
//
// Powered by CP Editor (https://cpeditor.org)
#include<bits/stdc++.h>
using namespace std;
#define int long long
#define lowbit(x) ((x)&(-(x)))
#define lg2(x) ((int)(__lg(x)/__lg(2)))
typedef long long LL;
typedef unsigned long long ull;
const int N=1e6+10,INF=2e9+10;
inline int read(){
int ret=0,f=1;
char ch=getchar();
while(ch<'0'||ch>'9'){ if(ch=='-') f=-f; ch=getchar(); }
while(ch>='0'&&ch<='9') ret=ret*10+ch-'0',ch=getchar();
return ret*f;
}
inline void write(int x){
if(x<0){ putchar('-'); x=-x; }
if(x>9) write(x/10);
putchar(x%10+'0');
}
int n,m,a[N],sum,suf[2][N],ans;
signed main(){
n=read(),m=read();
for(int i=1;i<=n;++i) a[i]=read();
for(int t=0;t<=m-1;++t){
sum=0;
for(int i=1;i<=n;++i){
if((a[i]>>t)&1){
suf[1][i]=suf[1][i-1]+1;
suf[0][i]=suf[0][i-1];
}else{
suf[1][i]=suf[0][i-1];
suf[0][i]=suf[1][i-1]+1;
}
sum+=suf[1][i];
}
ans+=(sum<<t);
}
write(ans);
return 0;
}F-草方块与牛排
题目链接
F-草方块与牛排题目分析
小清新构造题.
首先,我们讨论何时有解.
这要求使用的牛排数量
是整数,
也即
是
的倍数,
故
需是
的倍数,故
模
必为
或
.
考虑对棋盘进行染色,奇数行填
,偶数行填
,
那么一个牛排内要么有
个
、
个
, 要么有
个
、
个
;
设第一种牛排有
个,第二种有
个,则
,
那么除去草坪之后,整个棋盘上
有
个,
有
个,
由于
的个数应等于
的个数,
因此
,
也即
,
因此
为偶数.
假若
模
余
,即
,
带入得
,
这说明
是两个奇数的乘积,故
是奇数,
这与前面的论证矛盾,因此假设错误,
这表明
只可能是
型数字.
下证明
一定存在构造方案:
容易发现两个牛排可拼成一个
或
的长方形,
用这个长方形可以把挖去的
的草坪的两侧填满(因为剩下的是
与
的区域),
那么就只剩下一个
的正方形,
显然,使用两个
的长方形可以拼成一个
的正方形,
的正方形只需扩大
倍,证毕.
代码就蛮好写的了 qwq
代码
// Problem: 草方块与牛排
// Contest: NowCoder
// URL: https://ac.nowcoder.com/acm/contest/41173/F
// Memory Limit: 524288 MB
// Time Limit: 2000 ms
//
// Powered by CP Editor (https://cpeditor.org)
#include<bits/stdc++.h>
using namespace std;
#define lowbit(x) ((x)&(-(x)))
#define lg2(x) ((int)(__lg(x)/__lg(2)))
typedef long long LL;
typedef unsigned long long ull;
const int N=1e6+10,INF=2e9+10;
inline int read(){
int ret=0,f=1;
char ch=getchar();
while(ch<'0'||ch>'9'){ if(ch=='-') f=-f; ch=getchar(); }
while(ch>='0'&&ch<='9') ret=ret*10+ch-'0',ch=getchar();
return ret*f;
}
inline void write(int x){
if(x<0){ putchar('-'); x=-x; }
if(x>9) write(x/10);
putchar(x%10+'0');
}
int n;
inline int get(int x,int y){
return (x-1)*n+y;
}
void print1(int x,int y){
write(get(x,y)),putchar(' ');
write(get(x,y+1)),putchar(' ');
write(get(x,y+2)),putchar(' ');
write(get(x+1,y)),putchar('\n');
write(get(x+1,y+3)),putchar(' ');
write(get(x+1,y+2)),putchar(' ');
write(get(x+1,y+1)),putchar(' ');
write(get(x,y+3)),putchar('\n');
}
void print2(int x,int y){
write(get(x,y)),putchar(' ');
write(get(x+1,y)),putchar(' ');
write(get(x+2,y)),putchar(' ');
write(get(x,y+1)),putchar('\n');
write(get(x+3,y+1)),putchar(' ');
write(get(x+2,y+1)),putchar(' ');
write(get(x+1,y+1)),putchar(' ');
write(get(x+3,y)),putchar('\n');
}
int main(){
n=read();
if(n%4==2){
write((n*n-4)/4),putchar('\n');
for(int j=3;j<=n;j+=4)
for(int i=1;i<=n;i+=2)
print1(i,j);
for(int i=3;i<=n;i+=4) print2(i,1);
}else write(-1);
return 0;
}总结:
这次的小白月赛比较偏向思维与基础,感觉难度其实偏低了一些 qwq
点个赞再走喵 awa
作者:


汤臣倍健公司氛围 420人发布