洛谷网校举行了期末考试,同学们经过课程的学习,考出了优异的成绩。
Z 在考试中获得了第一名,yz 在考试中获得了第二名,老师决定买一些饼干奖励两名小朋友。
老师买了三盒饼干,第一盒有 a a a 块饼干,第二盒有 b b b 块饼干,第三盒有 c c c 块饼干。老师决定将这三盒饼干奖励给 Z 和 yz,三盒饼干不可以被拆开奖励。
老师希望 Z 拿到的饼干块数不少于 yz,但又希望两人拿到的饼干数量差距尽可能小,请问 Z 和 yz 各拿到几块饼干?
输入一行三个整数,分别为 a , b , c a,b,c a,b,c。
输出一行两个整数,由空格分隔。第一个整数代表 Z 拿到的饼干数量,第二个整数代表 yz 拿到的饼干数量。
3 1 5
5 4
3 3 5
6 5
Z 拿走 5 5 5 块饼干,yz 拿走 3 + 1 = 4 3+1=4 3+1=4 块饼干。
Z 拿走 3 + 3 = 6 3+3=6 3+3=6 块饼干,yz 拿走 5 5 5 块饼干。
题目有两个要求,最重要的是Z 拿到的饼干块数不少于 yz!!!在满足前者的前提下第二个要求是希望两人拿到的饼干数量差距尽可能小。
#include
using namespace std;
#define IOS ios::sync_with_stdio(0),cin.tie(0),cout.tie(0)
#define endl "\n"
#define int long long
#define repn(i,o,n) for(int i=o;i<=n;i++)
#define rep(i,o,n) for(int i=o;i<n;i++)
int a[4];
void solve(){
repn(i,1,3) cin>>a[i];
sort(a+1,a+4);
int ans1,ans2;
if(a[1]+a[2]!=a[3]){//两个小的加起来和最大的不相等,取较大值的已给第一名
if(a[1]+a[2]>a[3]){
ans1=a[1]+a[2];
ans2=a[3];
}else{
ans1=a[3];
ans2=a[1]+a[2];
}
}else{//!!!两者相等时,题目要求了Z 拿到的饼干块数不少于 yz
ans1=a[3]+a[1];//有要求两者差距尽可能小,所以我们拿一个最大的和一个最小的
ans2=a[2];
}
cout<<ans1<<' '<<ans2;
}
signed main(){
// IOS;
int T=1;
// cin>>T;
while(T--){
solve();
}
return 0;
}
/*
*/
老师有 N N N 块饼干,要分给 k k k 名小朋友。
每名小朋友至少拿到一块饼干,老师想让每名小朋友拿到的饼干数量都不一样多,请问老师能否实现这个目标。
本题单个测试点内有多组测试数据。
输入共 T + 1 T + 1 T+1 行。
输入第一行为一个整数 T T T,代表测试数据组数。
接下来 T T T 行,每行两个整数,分别为 N , k N,k N,k。
输出共 T T T 行,依次对应 T T T 组测试数据。如果该组测试数据
Yes
。No
。1
1 1
Yes
1
5 3
No
#include
using namespace std;
#define IOS ios::sync_with_stdio(0),cin.tie(0),cout.tie(0)
#define endl "\n"
#define int long long
void solve(){
int n,k;
cin>>n>>k;
if(n==1) {//注意特判一下
cout<<"Yes"<<endl;
return ;
}
int sum=(1+k)*k/2;
if(sum>n) cout<<"No"<<endl;
else cout<<"Yes"<<endl;
}
signed main(){
// IOS;
int T=1;
cin>>T;
while(T--){
solve();
}
return 0;
}
/*
*/
跳房子,也叫跳飞机,是一种世界性的儿童游戏,也是中国民间传统的体育游戏之一,趣味性、娱乐性极强,曾深受广大儿童的喜爱。
现在我们给出一种简易跳房子游戏的玩法:
n n n 个格子从左到右一字形排开,从左到右依次被标号为 1 , 2 , ⋯ , n 1, 2, \cdots, n 1,2,⋯,n。每一个格子上都有一个正整数, i i i 号格子上的正整数是 a i a _ i ai。
这个游戏的规则如下:初始时玩家站在 1 1 1 号格子上,需要做若干次跳跃。每一次跳跃时,玩家需要从当前格子向前跳「当前格子上写的整数」数量的格子。形式化地讲,如果玩家当前处于 x x x 号格子,玩家需要跳到 x + a x x + a _ x x+ax 号格子上。
如果玩家跳到 n n n 号格子右侧的位置,称玩家出界;如果玩家恰好跳到 n n n 号格子上,称玩家胜利。这两种情况下玩家都需要停止跳跃。
现在给定格子数量和格子上的整数,你需要求解:
输入共两行。
第一行为一个整数 n n n,代表格子的数量。
第二行为 n n n 个整数 a 1 , a 2 , ⋯ , a n a _ 1, a _ 2, \cdots, a _ n a1,a2,⋯,an,代表每个格子上的数字。
输出共两行。
第一行为一个字符串。如果玩家在停止跳跃后恰好跳到 n n n 号格子上,输出 Yes
,否则输出 No
。
第二行一个整数,代表玩家的总跳跃次数。
6
1 1 3 7 8 5
Yes
3
4
2 7 3 5
No
2
对于 100 % 100\% 100% 的数据,保证 1 ≤ n ≤ 1 0 6 1 \leq n \leq 10 ^ 6 1≤n≤106, 1 ≤ a i ≤ 1 0 4 1 \leq a _ i \leq 10 ^ 4 1≤ai≤104。
测试点编号 | n n n | 特殊性质 |
---|---|---|
1 1 1 | = 1 = 1 =1 | 无 |
2 ∼ 4 2 \sim 4 2∼4 | ≤ 100 \leq 100 ≤100 | 无 |
5 5 5 | ≤ 1 0 6 \leq 10 ^ 6 ≤106 | a i = 1 a _ i = 1 ai=1 |
6 , 7 6, 7 6,7 | ≤ 1 0 6 \leq 10 ^ 6 ≤106 | a i = 2 a _ i = 2 ai=2 |
8 ∼ 10 8 \sim 10 8∼10 | ≤ 1 0 6 \leq 10 ^ 6 ≤106 | 无 |
模拟题,按照题目要求模拟即可,具体步骤请看代码
#include
using namespace std;
#define IOS ios::sync_with_stdio(0),cin.tie(0),cout.tie(0)
#define endl "\n"
#define int long long
#define repn(i,o,n) for(int i=o;i<=n;i++)
#define rep(i,o,n) for(int i=o;i<n;i++)
const int N = 2e6+10, INF=1e18+10;
int a[N];
void solve(){
int n;
cin>>n;
for(int i=1;i<=n;i++) cin>>a[i];
int res=0,i=1,now=1;
if(n==1){//特判!!!
cout<<"Yes"<<endl;
cout<<0<<endl;
return ;
}
while(1){
now+=a[i];//移动a[i]步
i+=a[i];//注意下标也要加a[i]
res++;//步数加1
if(now==n){//到达终点,游戏结束!
cout<<"Yes"<<endl;
cout<<res;
return;
}
//cout<
if(now>n) break;//越界,游戏结束!
}
cout<<"No"<<endl;
cout<<res;
}
signed main(){
// IOS;
int T=1;
// cin>>T;
while(T--){
solve();
}
return 0;
}
/*
*/
给定 A , B , C , D , E , F , G , P , X 1 , X 2 , Y 1 , Y 2 A, B, C, D, E, F, G, P, X_1, X_2, Y_1, Y_2 A,B,C,D,E,F,G,P,X1,X2,Y1,Y2,求当 X 1 ≤ x ≤ X 2 X _ 1 \leq x \leq X _ 2 X1≤x≤X2, Y 1 ≤ y ≤ Y 2 Y _ 1 \leq y \leq Y _ 2 Y1≤y≤Y2 且 x , y x, y x,y 均为整数时
f ( x , y ) = ( A x 3 + B y 3 + C x 2 y + D x y 2 + E x y + F x + G y ) m o d P f(x, y) = (A x ^ 3 + B y ^ 3 + C x ^ 2 y + Dxy ^ 2 + Exy + Fx + Gy) \bmod P f(x,y)=(Ax3+By3+Cx2y+Dxy2+Exy+Fx+Gy)modP
的最大值。
输入共一行十二个整数 A , B , C , D , E , F , G , P , X 1 , X 2 , Y 1 , Y 2 A, B, C, D, E, F, G, P, X_1, X_2, Y_1, Y_2 A,B,C,D,E,F,G,P,X1,X2,Y1,Y2。
输出一个整数,代表 f ( x , y ) f(x, y) f(x,y) 的最大值。
3 2 5 6 1 4 2 998244353 1 2 1 3
266
当 x x x 为 1 1 1 到 2 2 2 之间的整数, y y y 为 1 1 1 到 3 3 3 之间的整数时,函数 f ( x , y ) f(x,y) f(x,y) 的值如下:
f ( 1 , 1 ) = 23 , f ( 1 , 2 ) = 63 , f ( 1 , 3 ) = 139 f ( 2 , 1 ) = 70 , f ( 2 , 2 ) = 144 , f ( 2 , 3 ) = 266 f(1,1)=23,\ f(1,2)=63,\ f(1,3)=139\\ f(2,1)=70,\ f(2,2)=144,\ f(2,3)=266 f(1,1)=23, f(1,2)=63, f(1,3)=139f(2,1)=70, f(2,2)=144, f(2,3)=266
最大值为 f ( 2 , 3 ) f(2,3) f(2,3),即 266 266 266。
对于 100 % 100\% 100% 的数据,保证 1 ≤ A , B , C , D , E , F , G , P ≤ 1 0 9 1 \leq A, B, C, D, E, F, G, P \leq 10 ^ 9 1≤A,B,C,D,E,F,G,P≤109, 1 ≤ X 1 ≤ X 2 ≤ 1 0 3 1 \leq X _ 1 \leq X _ 2 \leq 10 ^ 3 1≤X1≤X2≤103, 1 ≤ Y 1 ≤ Y 2 ≤ 1 0 3 1 \leq Y _ 1 \leq Y _ 2 \leq 10 ^ 3 1≤Y1≤Y2≤103。
遍历一遍(x,y)即可,刚开始以为是个数论题哈哈,吓得直接跳过了,回头一看数据范围x,y只有1e3,也就是说暴力的话时间复杂度为O(n^2),1e6不会超时间限制!
#include
using namespace std;
#define IOS ios::sync_with_stdio(0),cin.tie(0),cout.tie(0)
#define endl "\n"
#define int long long
#define repn(i,o,n) for(int i=o;i<=n;i++)
#define rep(i,o,n) for(int i=o;i<n;i++)
const int N = 2e5+10, INF=1e18+10;
int a,b,c,d,e,f,g,p,X1,X2,Y1,Y2;
int calc(int x,int y){
return (a*x*x*x+b*y*y*y+c*x*x*y+d*x*y*y+e*x*y+f*x+g*y)%p;
}
void solve(){
cin>>a>>b>>c>>d>>e>>f>>g>>p>>X1>>X2>>Y1>>Y2;
int res=0;
for(int i=X1;i<=X2;i++)
for(int j=Y1;j<=Y2;j++){
res=max(res,calc(i,j));
}
cout<<res<<endl;
}
signed main(){
// IOS;
int T=1;
// cin>>T;
while(T--){
solve();
}
return 0;
}
/*
*/
idea 提供者: bj12z_jiasiyuan
验题:卷王
有 n − 1 n - 1 n−1 只小跳蛙在池塘中,依次被编号为 1 , 2 , ⋯ , n − 1 1, 2, \cdots, n - 1 1,2,⋯,n−1。池塘里有 n n n 个位置,每一个位置上有一个数字 a i a_i ai。如果 a i = 0 a_i = 0 ai=0,则表示这个位置是一个空位;否则表示这个位置上存在一个编号为 a i a_i ai 的小跳蛙。
接下来的 n − 1 n-1 n−1 分钟,小跳蛙们将进行跳跃。第 i i i 分钟,编号为 i i i 的小跳蛙将跳到空位上。
请你输出 n − 1 n-1 n−1 分钟后池塘中每个位置的数字,即每个位置是否为空、小跳蛙编号是多少。
输入共两行。
第一行一个整数 n n n。
第二行 n n n 个整数 a 1 , a 2 , ⋯ , a n a _ 1, a _ 2, \cdots, a _ n a1,a2,⋯,an。
输出一行 n n n 个整数 a 1 , a 2 , ⋯ , a n a _ 1, a _ 2, \cdots, a _ n a1,a2,⋯,an。 表示 n − 1 n-1 n−1 分钟后池塘的状态。
5
1 2 0 3 4
2 3 1 4 0
0 2 1 3 4
2 0 1 3 4
2 3 1 0 4
2 3 1 4 0
因此最终池塘的状态为 2 3 1 4 0
。
对于 50 % 50\% 50% 的数据, 1 ≤ n ≤ 1 0 3 1 \leq n \leq 10 ^ 3 1≤n≤103。
对于 100 % 100\% 100% 的数据, 1 ≤ n ≤ 1 0 6 1 \leq n \leq 10^6 1≤n≤106,保证序列 a a a 是一个 0 ∼ n − 1 0 \sim n - 1 0∼n−1 这些数字的排列。
可以用map记录编号对应的下标,第i分钟就让编号为i的蛤蟆与空位(即编号0)交换位置
#include
using namespace std;
#define IOS ios::sync_with_stdio(0),cin.tie(0),cout.tie(0)
#define endl "\n"
#define int long long
#define repn(i,o,n) for(int i=o;i<=n;i++)
#define rep(i,o,n) for(int i=o;i<n;i++)
const int N = 1e6+10, INF=1e18+10;
int n,a[N];
unordered_map<int,int> mp;//编号->下标的映射
void solve(){
cin>>n;
for(int i=1;i<=n;i++){
cin>>a[i];
mp[a[i]]=i;
}
for(int i=1;i<=n;i++){
int x=mp[i];//编号为i的下标
int y=mp[0];//编号为0的下标
swap(a[x],a[y]);//交换位置
mp[0]=x;
mp[i]=y;
// for(int i=1;i<=n;i++)
// cout<
// cout<
}
for(int i=1;i<=n;i++)
cout<<a[i]<<' ';
}
signed main(){
IOS;
int T=1;
// cin>>T;
while(T--){
solve();
}
return 0;
}
/*
*/
一张字符图片由 n n n 行 m m m 列,共 n × m n\times m n×m 个字符组成,第 i i i 行第 j j j 列的字符为 s i , j s_{i,j} si,j。如下图所示,为一个 4 × 3 4\times 3 4×3 的字符图片。
%%%
$$$
@w@
!!!
现在,需要将图像放大 k k k 倍,得到 k n × k m kn \times km kn×km 的图片。原图片的每个字符都需要重复 k 2 k^2 k2 次,作为新图像中 k × k k\times k k×k 的一个区域,各字符的相对位置不变。
将上面给出的例子放大 2 2 2 倍,将得到如下图像:
%%%%%%
%%%%%%
$$$$$$
$$$$$$
@@ww@@
@@ww@@
!!!!!!
!!!!!!
输入 n + 1 n+1 n+1 行。
输入的第一行为三个整数 n , m , k n,m,k n,m,k。
接下来 n n n 行,每行 m m m 个字符,表示字符图片。
输出 n k nk nk 行,每行 m k mk mk 个字符,表示变换后的字符图片。
4 3 2
%%%
$$$
@w@
!!!
%%%%%%
%%%%%%
$$$$$$
$$$$$$
@@ww@@
@@ww@@
!!!!!!
!!!!!!
观察样例,我们可以看出每个字符需要输出k次,横纵长度都扩大了k倍
#include
using namespace std;
#define IOS ios::sync_with_stdio(0),cin.tie(0),cout.tie(0)
#define endl "\n"
#define int long long
#define repn(i,o,n) for(int i=o;i<=n;i++)
#define rep(i,o,n) for(int i=o;i<n;i++)
const int N = 2e3+10, INF=1e18+10;
int n,m,k;
char g[N][N];
void solve(){
cin>>n>>m>>k;
repn(i,1,n)
repn(j,1,m)
cin>>g[i][j];
for(int i=1;i<=n;i++){
for(int u=1;u<=k;u++){//每个字母输出k次
for(int j=1;j<=m;j++){
for(int p=1;p<=k;p++)
cout<<g[i][j];
}
cout<<endl;//注意换行
}
}
}
signed main(){
// IOS;
int T=1;
// cin>>T;
while(T--){
solve();
}
return 0;
}
/*
*/
给定一个正整数 n n n,以及操作次数 q q q。对于每次操作,给出一个正整数 k k k,要求:让 n n n 加上一个非负整数 x x x,使得 n n n 在二进制下的第 k k k 位(从右往左数)是 1 1 1,并在符合要求的情况下,令 x x x 最小。
请注意,每次操作都会让 n n n 变为 n + x n + x n+x,会影响后续操作。
小山需要求出,所有的 x x x 之和是多少。
输入共 q + 1 q + 1 q+1 行。
第一行两个整数 n n n 和 q q q。
接下来 q q q 行,每行一个正整数 k k k,表示要让 n n n 在二进制下从右往左数的第 k k k 位是 1 1 1。
一行一个整数,表示所有的 x x x 之和。
5 3
2
3
4
3
5 5 5 在二进制下是 101 101 101。
最终输出结果是 1 + 0 + 2 = 3 1+0+2=3 1+0+2=3。
对于 100 % 100\% 100% 的数据, 1 ≤ n < 2 32 , 1 ≤ q ≤ 1 0 5 , 1 ≤ k ≤ 32 1\le n < 2^{32},1\le q\le 10^5,1 \le k\le 32 1≤n<232,1≤q≤105,1≤k≤32。
测试点编号 | n n n | q q q | k k k |
---|---|---|---|
1 1 1 | ≤ 4 \leq 4 ≤4 | ≤ 10 \leq 10 ≤10 | ≤ 2 \leq 2 ≤2 |
2 , 3 2, 3 2,3 | ≤ 4 \leq 4 ≤4 | ≤ 10 \leq 10 ≤10 | ≤ 32 \leq 32 ≤32 |
4 , 5 4, 5 4,5 | ≤ 1024 \leq 1024 ≤1024 | ≤ 1000 \leq 1000 ≤1000 | ≤ 10 \leq 10 ≤10 |
6 , 7 6, 7 6,7 | < 2 32 < 2 ^ {32} <232 | ≤ 10 \leq 10 ≤10 | ≤ 32 \leq 32 ≤32 |
8 ∼ 10 8 \sim 10 8∼10 | < 2 32 < 2 ^ {32} <232 | ≤ 1 0 5 \leq 10 ^ 5 ≤105 | ≤ 32 \leq 32 ≤32 |
考察的二进制位运算,手写一下我们发现我们需要取后k位,那么该怎么取呢?比如n=6,二进制是110去后两位,1<<2是100,此时再减一变为011,在与上n为010,即可取得后两位,取后k位亦是如此。
再用1<<(k-1)减去n的后k位即为让从右往左数的第 k 位变为 1差的值。
#include
using namespace std;
#define IOS ios::sync_with_stdio(0),cin.tie(0),cout.tie(0)
#define endl "\n"
#define int long long
#define repn(i,o,n) for(int i=o;i<=n;i++)
#define rep(i,o,n) for(int i=o;i<n;i++)
const int N = 2e5+10, INF=1e18+10;
void solve(){
int n,q,sum=0;
cin>>n>>q;
while(q--){
int k;
cin>>k;
//cout<
if(n&(1LL*1<<(k-1))) continue;//已经是1
int x=(1LL*1<<(k-1))-n&((1LL*1<<k)-1);
n+=x;
sum+=x;
//cout<<"**"<
}
cout<<sum;
}
signed main(){
// IOS;
int T=1;
// cin>>T;
while(T--){
solve();
}
return 0;
}
/*
*/
你说得对,后面忘了。
在洛谷入门赛/语言月赛出题 QQ 群里,著名洛谷管理员蓝边铅球老师的群名片是『原神玩家』。
现在,扶苏给了你一个字符串 s s s,她想请你求出:有多少种方案可以在 s s s 中取出两个子串 s [ l 1 , r 1 ] , s [ l 2 , r 2 ] s[l_1, r_1], s[l_2, r_2] s[l1,r1],s[l2,r2],满足:
两个方案不同,当且仅当两个方案中 l 1 , r 1 , l 2 , r 2 l_1, r_1, l_2, r_2 l1,r1,l2,r2 至少有一个对应不同。
输入只有一行,表示字符串 s s s。
输出一行一个整数表示答案。
Genshinplayerplayer
2
ExpectedIsAGenshinplayerWhoLikesToBeAGenshinplayer
3
主要就是找字串再在主串中出现的次数,先找s1=“Genshin”,然后再找s2="player"出现的次数,然后再找下一个s1,以及下一个s1后面s2出现了多少次,直到找不到s1。这里用find函数来查找子串。其实也可以用kmp算法求字串,不过有点麻烦,属实是杀鸡用牛刀了( ̄︶ ̄)。
#include
using namespace std;
#define IOS ios::sync_with_stdio(0),cin.tie(0),cout.tie(0)
#define endl "\n"
#define int long long
#define repn(i,o,n) for(int i=o;i<=n;i++)
#define rep(i,o,n) for(int i=o;i<n;i++)
const int N = 2e5+10, INF=1e18+10;
string s1="Genshin",s2="player";
void solve(){
string s;
cin>>s;
int res=0;
int pos1=s.find(s1,0);
while(s.find(s1,pos1)!=-1){
if(pos1!=-1){
int pos2=s.find(s2,pos1),num=0;
while(s.find(s2,pos2)!=-1){
num++;
pos2=s.find(s2,pos2+1);
}
res+=num;
// cout<
}
pos1=s.find(s1,pos1+1);
}
cout<<res;
}
signed main(){
// IOS;
int T=1;
// cin>>T;
while(T--){
solve();
}
return 0;
}
/*
*/
本次比赛难度只有div4,但比赛中好几道没有全过,甚至有的只过了两三个点(H)。