前言
能力有限,只写/补了一些自己能力范围内的。
第3场
A
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 1005;
int vis[N];
void solve() {
ll n;
cin>>n;
if(n%2==1)cout<<"Yes";
else cout<<"No";
};
int main() {
ios::sync_with_stdio(false);
cin.tie(0),cout.tie(0);
solve();
return 0;
}
F
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 1005;
int vis[N];
void solve() {
int n,a,b,c;
cin>>n>>a>>b>>c;
if((a+b+c>=n)&&(a+b+c<=2*n))cout<<"Yes\n";
else cout<<"No\n";
};
int main() {
ios::sync_with_stdio(false);
cin.tie(0),cout.tie(0);
int T;
cin>>T;
while(T--)solve();
return 0;
}
M
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 1005;
map<int,int>mp;
int vis[N];
void solve() {
string s;
cin>>s;
for(int i=0;i<s.size();i++){
int t = s[i];
vis[t]++;
};
if(vis[99]&&vis[100]&&vis[101]&&vis[110]&&vis[111]==2&&vis[114]&&vis[119]){
cout<<"happy new year";
}
else cout<<"I AK IOI";
};
int main() {
ios::sync_with_stdio(false);
cin.tie(0),cout.tie(0);
solve();
return 0;
}
L
离散里面的欧拉回路,太久没学离散不会做了。。。。
有空再补了
第4场
K
签到
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 1005;
void solve() {
int x,y,z,a,b,c;
cin>>x>>y>>z>>a>>b>>c;
int a1,a2,a3;
a1 = x*a;
a2 = y*b;
a3 = z*c;
int fi = max(a1,a2);
fi = max(fi,a3);
cout<<fi<<'\n';
};
int main() {
ios::sync_with_stdio(false);
cin.tie(0),cout.tie(0);
int T;
cin>>T;
while(T--)solve();
return 0;
}
I
开两个队列遍历
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
void solve() {
queue<int>q1,q2;
int n;
cin>>n;
string s;
cin>>s;
string tar = "uwawauwa";
int i=0;
while(s.find("u",i)!=-1){
q1.push(s.find("u",i));
i = s.find("u",i) + 1 ;
};
i=0;
while(s.find(tar,i)!=-1){
q2.push(s.find(tar,i));
i = s.find(tar,i) + 1 ;
};
int ans = 0;
while(!q1.empty()&&!q2.empty()){
int t1 = q1.front();
int t2 = q2.front();
if(t1+1<t2){
ans +=q2.size();
q1.pop();
}
else q2.pop();
};
cout<<ans<<'\n';
};
int main() {
ios::sync_with_stdio(false);
cin.tie(0),cout.tie(0);
int T;
cin>>T;
while(T--)solve();
return 0;
}
E
这里主要是图的对角线的性质。
- 左上到右下的每个坐标的 x − y x-y x−y 一致
- 左下到右上的每个坐标的 x + y x+y x+y 一致
代码:
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 1005;
void solve() {
map<ll,ll>mp1,mp2;
ll a[N][N];
ll n,m,x;
cin>>n>>m;
for(int i=1; i<=n; i++) {
for(int j=1; j<=m; j++) {
cin>>x;
mp1[i+j]+=x;
mp2[i-j]+=x;
a[i][j] = x;
}
};
// 遍历
ll ans = 0;
for(int i=1; i<=n; i++)
for(int j=1; j<=m; j++) {
ll tmp = mp1[i+j] + mp2[i-j] - a[i][j];
ans = max(ans,tmp);
}
cout<<ans<<'\n';
};
int main() {
ios::sync_with_stdio(false);
cin.tie(0),cout.tie(0);
int T;
cin>>T;
while(T--)solve();
return 0;
}
B
很典的字符串,赛时看范围猜到是枚举了,太菜了做不出来字符串,太痛苦了
枚举思路是枚举问号可产生的字符串个数,然后枚举每种字符串翻转的可能,复杂度是 O ( 2 n ) O(2^n) O(2n)
参考这位师傅写cmp的思路:2025牛客寒假算法基础集训营4(B)-优快云博客
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 1005;
ll mod = 1e9+7;
ll cmp(string s){
ll c1=0,c2=0;
for(int i=1;i<=s.size();i++){
if(s[i-1]=='0'&&s[i]=='1')c1++;
if(s[i-1]=='1'&&s[i]=='0')c2++;
};
return c1==c2;
}
void solve() {
ll n;
cin>>n;
string s;
cin>>s;
queue<string>q;
q.push(s);
// 产生多少种字符串
while(true){
string tmp = q.front();
int pos = tmp.find('?');
if(pos!=-1){
q.pop();
string t1 = tmp;
t1[pos] = '0';
q.push(t1);
t1[pos] = '1';
q.push(t1);
}
else break;
};
//cout<<"q = "<<q.size()<<endl;
ll ans = 0;
// 遍历每种字符串的val
while(!q.empty()){
string tmp = q.front();
q.pop();
for(int i=0;i<tmp.size();i++){
string tmp2 = tmp;
if(tmp2[i]=='0')tmp2[i]='1';
else tmp2[i]='0';
ans +=cmp(tmp2);
}
ans%=mod;
};
cout<<ans<<'\n';
};
int main() {
ios::sync_with_stdio(false);
cin.tie(0),cout.tie(0);
int T;
cin>>T;
while(T--)solve();
return 0;
}
这个的hard version还不会写,感觉找规律对我来说太恶心了一点TT
D
字符串的消消乐版本,auto真的挺好用的。。。。。
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 1005;
void solve() {
int n,m;
string a,b;
cin>>n>>m;
cin>>a>>b;
// 区分长短字符串,n a为长字符串
if(n<m){
swap(n,m);
swap(a,b);
};
// 长串为主
map<int,int>mp;
for(int i=0;i<a.size();i++)mp[a[i]]++;
int sum=0;
// 对比长短字符串中的差距
for(int i=0;i<b.size();i++){
if(mp[b[i]])mp[b[i]]--;
else sum++;
}
int ans = 0;
for(auto p:mp){
if(p.second&1)ans++;
};
if(sum >=ans)ans = sum;
else{
ans -=sum;
ans/=2;
ans +=sum;
};
cout<<ans<<'\n';
};
int main() {
ios::sync_with_stdio(false);
cin.tie(0),cout.tie(0);
int T;
cin>>T;
while(T--)solve();
return 0;
}
第6场
由于这场有事出门了,让朋友帮忙签了一道,赛后才回来补的
A
#include<iostream>
using namespace std;
int a[200009];
int T,n;
int ans;
int main()
{
cin>>T;
while(T--)
{
ans=0;
cin>>n;
for(int i=1;i<=n;i++)
{
cin>>a[i];
if(a[i]!=a[i-1])
ans++;
}
cout<<ans<<endl;
}
return 0;
}
K
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 1005;
void solve() {
int x,y;
cin>>x>>y;
int sum = 2*x+1;
if(abs(sum-y)%4==0)cout<<"YES\n";
else cout<<"NO\n";
};
int main() {
ios::sync_with_stdio(false);
cin.tie(0),cout.tie(0);
int T;
cin>>T;
while(T--)
solve();
return 0;
}
L
一开始使用的是模拟的做法,想比较不同字母的个数,错误代码如下:
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 1005;
void solve() {
int n;
cin>>n;
string s;
cin>>s;
string tar = "CHICKEN";
if(n<7)cout<<"NO\n";
else{
int pos=0;
int mp[30];
for(int i=0;i<29;i++)mp[i] = 0;
for(int i=0;i<n;i++){
if(s[i]==tar[pos]&&pos<7)pos++;
else mp[s[i]-'A'+1]++;
};
//cout<<"pos = "<<pos<<endl;
if(pos!=7)cout<<"NO\n";
else{
int ans =0;
int sum = 0;
sort(mp+1,mp+27);
for(int i=26;i>0;i--){
ans = abs(ans-mp[i]);
sum +=mp[i];
//cout<<ans<<endl;
};
//cout<<ans<<endl;
//cout<<sum<<endl;
if(sum%2==0 &&!ans)cout<<"YES\n";
else cout<<"NO\n";
}
}
};
int main() {
ios::sync_with_stdio(false);
cin.tie(0),cout.tie(0);
int T;
cin>>T;
while(T--)
solve();
return 0;
}
后来在这个讨论发现了不足,求L的hack数据,L题采取栈模拟为什么不行呢?
发现是这种样例过不了
1
13
CHICKENXXYYZZ
那就是找数学规律了,AC代码如下:
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 1005;
void solve() {
int n;
cin>>n;
string s;
cin>>s;
string tar = "CHICKEN";
if(n<7)cout<<"NO\n";
else{
int pos=0;
int mp[30];
for(int i=0;i<29;i++)mp[i] = 0;
for(int i=0;i<n;i++){
if(s[i]==tar[pos]&&pos<7)pos++;
else mp[s[i]-'A'+1]++;
};
if(pos!=7)cout<<"NO\n";
else{
// 需要消除的
int maxx = 0;
for(int i=1;i<=26;i++)maxx = max(maxx,mp[i]);
int sum = n-7;
if(maxx<=sum-maxx && sum%2==0)cout<<"YES\n";
else cout<<"NO\n";
}
}
};
int main() {
ios::sync_with_stdio(false);
cin.tie(0),cout.tie(0);
int T;
cin>>T;
while(T--)
solve();
return 0;
}
C
很数列的数学题,距离学数学的日子已经太过久远了~
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 1005;
void solve() {
ll k;
cin>>k;
k *=2;
for(ll i=4;i<=k;i*=2)k+=2;
cout<<k<<'\n';
};
int main() {
ios::sync_with_stdio(false);
cin.tie(0),cout.tie(0);
int T;
cin>>T;
while(T--)
solve();
return 0;
}
J
模拟题,由于磨完后砍的伤害更高,所以优先必然是先磨再砍的,这样只用考虑是否要在磨的时候就开始砍,复杂度为 O ( n ) O(n) O(n)。
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 1005;
void solve() {
int n,x,y;
cin>>n>>x>>y;
int ans = 0;
// 从t时刻开始攻击
for(int t=1;t<=y;t++){
if(t>n)break; // 可加范围超过回合数
int kt = min(n,y) - t; // 从当前时刻开始可累计增加的攻击力
int len = min(x+t,n - min(n,y) + 1);
ans = max(ans,kt*(x+t) + (x+t+x+t-len+1)*len/2);
};
cout<<ans<<'\n';
};
int main() {
ios::sync_with_stdio(false);
cin.tie(0),cout.tie(0);
int T;
cin>>T;
while(T--)
solve();
return 0;
}