C++小白训练第一天
C++小白训练第一天
以下为牛客挑战
今日收获
b1=(t<=0?0:(t+B-1)/B);
(t+B-1)/B,这个就是向上取整,c++默认是向下取整
三目运运算符和向上取整 比较?运算1:运算2;
一个数&1就可以判断他的奇偶数性,奇数为1,偶数为0;
find(t.begin(),t.end(),x),去容器中找x,find(...) != t.end()这样就是没有找到
连续段的题目直接可以用两个参数代替,now,ans,
牛客挑战赛85
剑客花木兰

输入
4 5 3
1
7
15
101
输出
0 1
1 1
0 5
1 32
输入
2 5 5
3
20
输出
0 1
0 4
开始看到这个题目我没有特别去注意这个10的3次方的问题,然后就在想别的方法去,但是好像都过不了然后我看到10的3次方双层循环不会出事然后直接吗枚举
主要思路就是我们枚举A的次数,来得到B的次数,对体力的和进行比较看看和前一次的大小然后交换次数。,但是这个比较值最少要开到1e12来不然就会全部过不了。
解题代码
#include<bits/stdc++.h>
#define int long long
#define lll __uint128_t
#define PII pair<int ,int>
#define endl '\n'
using namespace std;
#define yn(ans) printf("%s\n", (ans)?"Yes":"No");//快速打印
#define YN(ans) printf("%s\n", (ans)?"YES":"NO");
#define REP(i, e) for (int i = 0; i < (e); ++i)
#define REP1(i, s, e) for (int i = (s); i <=(e); ++i)
#define TESTS int t; cin >> t; while (t--)
#define TEST
const int N=2e5+10,M=1e3+10,mod=1e9+7;
signed main(){
std::ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
int n,A,B;
cin>>n>>A>>B;
for(int i=0;i<n;i++){
int x;
cin>>x;
int max1=1e12;
int a,b;
for(int j=0;j<=A;j++){
int t=x-j*A;
int b1=(t<=0?0:(t+B-1)/B);//因为要填补完全,例如5生命,但是中有3,所以要补充就是向上取整,然后3 和3向上取整还是1;
int f=j*A+b1*B;
if(f<max1){
max1=f;
a=j;
b=b1;
}
}
cout<<a<<" "<<b<<endl;
}
return 0;
}
序列与变换

输入
3 6
20 17 24
输出
1 1

我的第一开始的思路是肯定要求出这个数的等差数列和s然后最少就可以排除一部分数据,然后剩下的我们发现到和s的奇偶性有点相同,
相同的为0,因为
把 aᵢ 一口气减掉总和
s = m+(m−1)+…+0 = m(m+1)/2
得到余量
r = aᵢ − s
因为 s 已经把“后面所有减法”一次性做完,所以 r 就是“减到最后还剩下的那个数”。
而“减偶数”不会翻转最低位,“减奇数”才会翻转最低位。
所以我们只要看这个和的奇偶性
解题代码
#include<bits/stdc++.h>
#define int long long
#define lll __uint128_t
#define PII pair<int ,int>
#define endl '\n'
using namespace std;
#define yn(ans) printf("%s\n", (ans)?"Yes":"No");//快速打印
#define YN(ans) printf("%s\n", (ans)?"YES":"NO");
#define REP(i, e) for (int i = 0; i < (e); ++i)
#define REP1(i, s, e) for (int i = (s); i <=(e); ++i)
#define TESTS int t; cin >> t; while (t--)
#define TEST
const int N=2e5+10,M=1e3+10,mod=1e9+7;
int a[N],b[N],c[N],pre[N];
signed main(){
std::ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
int m,n;
cin>>n>>m;
int cout0=0,cout1=0;
for(int i=0;i<n;i++){
cin>>a[i];
}
lll s=(m+1)*(m)/2;//必须开lll不然直接过不了
for(int i=0;i<n;i++){
if(a[i]<=s+1){
if((a[i]&1)==(s&1)){
cout0++;
}else{
cout1++;
}
}
}
cout<<cout0<<" "<<cout1<<endl;
return 0;
}
牛客周赛 Round 125
小苯的选择题

解题代码
#include<bits/stdc++.h>
#define int long long
#define lll __uint128_t
#define PII pair<int ,int>
#define endl '\n'
using namespace std;
#define yn(ans) printf("%s\n", (ans)?"Yes":"No");//快速打印
#define YN(ans) printf("%s\n", (ans)?"YES":"NO");
#define REP(i, e) for (int i = 0; i < (e); ++i)
#define REP1(i, s, e) for (int i = (s); i <=(e); ++i)
#define TESTS int t; cin >> t; while (t--)
#define TEST
const int N=2e5+10,M=1e3+10,mod=1e9+7;
int a[N],b[N],c[N],pre[N];
signed main(){
std::ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
string s;
string t="ABD";
cin>>s;
if(s=="ABD"){
cout<<4<<endl;
}else{
if(s=="AB"||s=="AD"||s=="BD"){
cout<<2<<endl;
}else{
if(find(t.begin(),t.end(),s[0])!=t.end()&&s.size()==1){
cout<<"2"<<endl;
}
else{
cout<<"0"<<endl;
}
}
}
return 0;
}
小苯的峰值序列

输入
3
5
3 1 4 1 5
6
2 3 1 4 2 3
2
1 1
输出
3 1 1 1 5
2 2 1 2 2 3
1 1
解题思路,我们只需要和两边的进行比较,直接就可以,让后面的直接等于前面的和后面的最大值就行了
就相当于是字典序最小了。
解题代码
#include<bits/stdc++.h>
#define int long long
#define lll __uint128_t
#define PII pair<int ,int>
#define endl '\n'
using namespace std;
#define yn(ans) printf("%s\n", (ans)?"Yes":"No");//快速打印
#define YN(ans) printf("%s\n", (ans)?"YES":"NO");
#define REP(i, e) for (int i = 0; i < (e); ++i)
#define REP1(i, s, e) for (int i = (s); i <=(e); ++i)
#define TESTS int t; cin >> t; while (t--)
#define TEST
const int N=2e5+10,M=1e3+10,mod=1e9+7;
int a[N],b[N],c[N],pre[N];
void solve(){
int n;
cin>>n;
for(int i=0;i<n;i++){
cin>>a[i];
}
for(int i=1;i<n-1;i++){
if(a[i]>a[i-1]&&a[i]>a[i+1]){
a[i]=a[i-1]>a[i+1]?a[i-1]:a[i+1];
}
}
for(int i=0;i<n;i++){
cout<<a[i]<<" ";
}
cout<<endl;
};
signed main(){
std::ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
TESTS{
solve();
};
return 0;
}
小苯排雷

输入
2
5
2 0 3 3 4
6
0 0 1 0 0 2
输出
5
3
段中最小值
本题的思路是我们只需要管一段的最小值。我们可以用一段之后的零来判断要不要加上单前的最小值,最后一个要特判,可能遇不到零,就是当遇到零时候,并且已经有最小值了就相加然后就可以得到
解题代码
#include<bits/stdc++.h>
#define int long long
#define lll __uint128_t
#define PII pair<int ,int>
#define INF (int)1e18
#define endl '\n'
using namespace std;
#define yn(ans) printf("%s\n", (ans)?"Yes":"No");//快速打印
#define YN(ans) printf("%s\n", (ans)?"YES":"NO");
#define REP(i, e) for (int i = 0; i < (e); ++i)
#define REP1(i, s, e) for (int i = (s); i <=(e); ++i)
#define TESTS int t; cin >> t; while (t--)
#define TEST
const int N=2e5+10,M=1e3+10,mod=1e9+7;
int a[N],b[N],c[N],pre[N];
void solve(){
int n;
cin>>n;
for(int i=0;i<n;i++){
cin>>a[i];
}
int ans=INF;
int sum=0;
for(int i=0;i<n;i++){
if(a[i]==0){
if(ans!=INF)sum+=ans;
ans=INF;
}else{
ans=min(ans,a[i]);
}
}
if(ans!=INF)sum+=ans;
cout<<sum<<endl;
};
signed main(){
std::ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
TESTS{
solve();
};
return 0;
}
小苯的01合并

2
4 2
0110
00
5 1
11010
0
输出
YES
NO
我们的目的是为了可以得到字符串s2,进行异或操作,我们明白从第一个位置到后面的某一个位置必需要异或和为第二个字母的第一个位置,所以我们可以得到

特判就是最后一个位置的直接到最后就行了,因为最后一个必须要合成最后一位
所以我们只需要特别判段一下就可以时间复杂度1n9。
解题代码
#include<bits/stdc++.h>
#define int long long
#define lll __uint128_t
#define PII pair<int ,int>
#define endl '\n'
using namespace std;
#define yn(ans) printf("%s\n", (ans)?"Yes":"No");//快速打印
#define YN(ans) printf("%s\n", (ans)?"YES":"NO");
#define REP(i, e) for (int i = 0; i < (e); ++i)
#define REP1(i, s, e) for (int i = (s); i <=(e); ++i)
#define TESTS int t; cin >> t; while (t--)
#define TEST
const int N=2e5+10,M=1e3+10,mod=1e9+7;
void solve(){
int n,m;
string A,B;
cin>>n>>m>>A>>B;
bool ok=true;
for(int i=0,j=0;j<m;j++){
if(i>=n){
ok=false;
break;
}
int a=A[i]-'0',b=B[j]-'0';//这个是每一个进行枚举
while (i<n-1&&a!=b){
a^=A[i+1]-'0';
i++;
}
if(j==m-1){
while(i<n-1){
a^=A[i+1]-'0';
i++;
}
}
if(a!=b){
ok=false;
}
i++;
}
if(ok==true){
cout<<"YES"<<endl;
}else{
cout<<"NO"<<endl;
}
};
signed main(){
std::ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
TESTS{
solve();
};
return 0;
}

浙公网安备 33010602011771号