河南萌新联赛2

河南萌新联赛2

1.B-宝石_2022河南萌新联赛第(二)场:河南理工大学 (nowcoder.com)

这种题肯定是先预处理两个点的值,如果然后再两重循环,看是否存在这个点的后面有三个点的乘积可以满足条件。如果满足就ok

#include<bits/stdc++.h>
using namespace std;
typedef pair<int,int> PII;
#define fel(i,x,y) for(int i=x;i<=y;i++)
#define fhl(i,x,y) for(int i=x;i>=y;i--)
#define pb push_back
#define IOS ios::sync_with_stdio(false); cin.tie(0); cout.tie(0);
#define inf 0x3fffffff
#define endl "\n"
//#define int long long//这个定义可以在main为signed main用
#define ll long long
#define x first
#define y second
const int N=2000;
ll n;
ll a[N];
unordered_map<ll,ll>mp;
int main()
{
IOS
cin>>n;
fel(i,1,n) cin>>a[i];
for(int i=2;i<=n;i++){
for(int j=i;j<=n;j++){//如果都从2开始循环肯定会有重复的从i开始就就可以了
mp[a[i]*a[j]]=i;//只要存最i的下标就可以了,因为j>=i
}
}
ll ans=0;
for(int i=1;i<n;i++){
for(int j=i+1;j<=n;j++){
if(a[i]==a[j]&&a[j]==0){//两个数都是0
ans++;
break;
}
if(a[j]==0||a[i]%a[j]!=0)continue;
if(mp[a[i]/a[j]]>i){
ans++;
break;
}
}
}
cout<<ans<<endl;
   return 0;
}

2.D-数对_2022河南萌新联赛第(二)场:河南理工大学 (nowcoder.com)

这个先对题目中的条件化简可以的到

a[l]y+a[l+1]y.......+a[r1]y+a[r]y<=x

很明显右边是原数组减去一个y之后的前缀和,那就是sum[r]-sum[l-1]<=x

再变下形就是sum[r]-x<=sum[l-1];这样就可以用树状数组每次查询一下大于sum[r]-x的值有多少就可以了。然后值域很大,离散化一下就ok.

#include<bits/stdc++.h>
using namespace std;
#define fel(i,x,y) for(int i=x;i<=y;i++)
#define fhl(i,x,y) for(int i=x;i>=y;i--)
#define pb push_back
#define IOS ios::sync_with_stdio(false); cin.tie(0); cout.tie(0);
#define inf 0x3fffffff
#define endl "\n"
typedef pair<int,int> PII;
#define x first
#define y second
#define ll long long
const int N=4e5+100;
int n;
ll a[N],x,y;
vector<ll>num;
int tree[N];//他把a[i]和a[i]-x存起来了所以要开两倍
int lowbit(int x){
return x&-x;
}
void add(int u,int x){//下标u加上x
for(int i=u;i<=num.size();i+=lowbit(i)){
tree[i]+=x;
}
}
int query(int u){
int ans=0;
for(int i=u;i;i-=lowbit(i)){
ans+=tree[i];
}
return ans;
}
int get(ll x){
return lower_bound(num.begin(),num.end(),x)-num.begin()+1;
}
int main(){
cin>>n>>x>>y;
num.pb(0);//因为查询的是S[l-1];就是可能存1-r这样满足条件的区间
fel(i,1,n) cin>>a[i],a[i]-=y;;
fel(i,1,n){
a[i]+=a[i-1];
num.pb(a[i]-x);
num.pb(a[i]);
}
sort(num.begin(),num.end());
num.erase(unique(num.begin(),num.end()),num.end());//忘了加上num.end()
add(get(0),1);
ll ans=0;
fel(i,1,n){
ans+=query(num.size())-query(get(a[i]-x)-1);//查找大于等于a[i]-x的值
add(get(a[i]),1);
}
cout<<ans<<endl;
return 0;
}

3.G-无限_2022河南萌新联赛第(二)场:河南理工大学 (nowcoder.com)

找规律的题感觉这个是蒙出来的,把前几项写一下发现了这个规律。

#include<bits/stdc++.h>
using namespace std;
typedef pair<int,char> PII;
#define fel(i,x,y) for(int i=x;i<=y;i++)
#define fhl(i,x,y) for(int i=x;i>=y;i--)
#define pb push_back
#define IOS ios::sync_with_stdio(false); cin.tie(0); cout.tie(0);
#define inf 0x3fffffff
#define endl "\n"
//#define int long long//这个定义可以在main为signed main用
#define ll long long
const int mod=998244353,N=1e6+100;
int a[N];
int main(){
int n;
cin>>n;
a[1]=1,a[2]=2;
for(int i=3;i<=n;i++){
a[i]=(a[i-1]+a[i-2]+1)%mod;
}
cout<<a[n]<<endl;
return 0;
}

4.H-0和1_2022河南萌新联赛第(二)场:河南理工大学 (nowcoder.com)

反正要么全是1,要么全是0。分两种情况讨论就好了。先以全变成0为例子。

考虑到两串连续的1中0的个数。如果之间只有一个0的话就考虑一次全部异或,那就只需要三次。如果中间有两个0的话那就分别异或两个连续串就好了。这就是需要四次。

#include<bits/stdc++.h>
using namespace std;
#define fel(i,x,y) for(int i=x;i<=y;i++)
#define fhl(i,x,y) for(int i=x;i>=y;i--)
#define pb push_back
#define IOS ios::sync_with_stdio(false); cin.tie(0); cout.tie(0);
#define inf 0x3fffffff
#define endl "\n"
typedef pair<int,int> PII;
#define x first
#define y second
#define ll long long
const int N=2000;
string s;
//解法大概就是看101需要两点,1011这个需要三点,1110011需要四点
int find(char x)
{
int len=s.length(),res=0;
vector<PII>ans;
for(int i=0;i<len;i++){
if(s[i]==x){
int j=i;
while(j<len&&s[j]==x)j++;
j--;
//判断是第二种情况
if(ans.size()&&j-i+1+ans.back().y-ans.back().x+1>=3&&i-ans.back().y==2){
res++;//把中间的0变成1
ans.back().y=j;
}
else{
ans.pb({i,j});
}
i=j;
}
}
for(auto i:ans){
if(i.y-i.x==0)res++;
else res+=2;
}
return res;
}
int main()
{
   cin>>s;
   cout<<min(find('0'),find('1'))<<endl;
   return 0;
}

 

5.I-22数_2022河南萌新联赛第(二)场:河南理工大学 (nowcoder.com)

搜索考虑减枝就好。

#include<bits/stdc++.h>
using namespace std;
#define fel(i,x,y) for(int i=x;i<=y;i++)
#define fhl(i,x,y) for(int i=x;i>=y;i--)
#define pb push_back
#define IOS ios::sync_with_stdio(false); cin.tie(0); cout.tie(0);
#define inf 0x3fffffff
#define endl "\n"
typedef pair<int,int> PII;
#define x first
#define y second
#define ll long long
const int N=2000;
//感觉像是搜索题,就是每次确定一个数再搜下一个数这样就最后如果是数之和等于位数两倍就可以了
ll ans,n;
void dfs(ll x,ll sum,ll step){//x是这个数是多少 ,sum是这个数的各个位数之和,step是这是个几位数
if(x>n||sum>20||step>10)return;
if(x&&sum==step*2){
ans++;
}
for(int i=0;i<=9;i++){
ll j=x*10+i;
if(j&&j<=n){
dfs(j,sum+i,step+1);
}
}
}
int main()
{
cin>>n;
dfs(0,0,0);
cout<<ans;
   return 0;
}
 
posted @   silky__player  阅读(45)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· winform 绘制太阳,地球,月球 运作规律
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· AI 智能体引爆开源社区「GitHub 热点速览」
· Manus的开源复刻OpenManus初探
· 写一个简单的SQL生成工具
点击右上角即可分享
微信分享提示