目录
A.造数
aA-造数_河南萌新联赛2024第(一)场:河南农业大学 (nowcoder.com)
倒过来思考,看最少几部可以将n变成0。
但有些部分需要贪心,当n为1和2时需要一步就可以完成,大于这个数分奇数偶数讨论,偶数给他除以2,奇数就直接使它变成偶数。
#include<bits/stdc++.h>
#define int long long
#define TEST int T;cin>>T;while(T--)
#define lowbit(x) x&(-x)
using namespace std;
const int N = 200010;
const int M = 2e14 + 10;
const int mod = 1e9 + 7;
inline void solve() {
int n;
cin >> n;
int ans = 0;
while (n) {
if(n==1||n==2)
{
ans++;
break;
}
else if(n%2==0)
{
ans++;
n/=2;
}
else
{
n--;
ans++;
}
}
cout<<ans<<"\n";
}
signed main() {
solve();
return 0;
}
B.爱探险的朵拉
B-爱探险的朵拉_河南萌新联赛2024第(一)场:河南农业大学 (nowcoder.com)
因为我们需要从每个点为起点开始遍历,我们可以用dfs查找最大答案。
但是单纯的dfs只能过百分之90的数据,所以我们这里需要记忆化搜索,用一个dp数组记录下值,这样可以减少重复遍历的时间。
#include<bits/stdc++.h>
#define int long long
#define TEST int T;cin>>T;while(T--)
#define lowbit(x) x&(-x)
using namespace std;
const int N = 200010;
const int M = 2e14 + 10;
const int mod = 1e9 + 7;
int n,a[N],v[N],sum=0,ans=0,dp[N];
int dfs(int i)
{
v[i]=1;
if(v[a[i]]==0) dp[i]=dfs(a[i])+1;
else dp[i]=1;
v[i]=0;
return dp[i];
}
inline void solve() {
cin>>n;
for(int i=1;i<=n;i++) cin>>a[i];
for(int i=1;i<=n;i++)
{
sum=0;
if(dp[i]==0) dfs(i);
ans=max(dp[i],ans);
if(ans==n) break;
}
cout<<ans<<"\n";
}
signed main() {
solve();
return 0;
}
C.有大家喜欢的零食吗
C-有大家喜欢的零食吗_河南萌新联赛2024第(一)场:河南农业大学 (nowcoder.com)
一开始没反应过来,后来发现就是一个二部图的最大匹配问题,需要用到匈牙利算法。
#include<bits/stdc++.h>
#define int long long
#define TEST int T;cin>>T;while(T--)
#define lowbit(x) x&(-x)
using namespace std;
const int N = 200010;
const int M = 2e14 + 10;
const int mod = 1e9 + 7;
vector<vector<int> >mp;
int n;
int match[N],v[N];
bool dfs(int x,int tag)
{
if(v[x]==tag) return false;
v[x]=tag;
for(auto k:mp[x])
{
if(!match[k]||dfs(match[k],tag))
{
match[k]=x;
return true;
}
}
return false;
}
inline void solve() {
cin>>n;
mp.resize(n+1);
for(int i=1;i<=n;i++)
{
int k;
cin>>k;
for(int j=1;j<=k;j++)
{
int p;
cin>>p;
mp[i].push_back(p);
}
}
int ans=0;
for(int i=1;i<=n;i++)
{
if(dfs(i,i)) ans++;
}
if(n-ans==0)
{
cout<<"Yes\n";
}
else
{
cout<<"No\n";
cout<<n-ans<<"\n";
}
}
signed main() {
solve();
return 0;
}
F.两难抉择新编
F-两难抉择新编_河南萌新联赛2024第(一)场:河南农业大学 (nowcoder.com)
我们先用一个变量ans记录所有元素的异或和。
因为可以取的是1到n/i,所以我们可以暴力求解,我们改变某一个数,那就用ans异或这个数,相当于将它去除ans,再异或改变后的数,那就完成了改变,用一个变量更新最大值。
#include<bits/stdc++.h>
#define int long long
#define TEST int T;cin>>T;while(T--)
#define lowbit(x) x&(-x)
using namespace std;
const int N = 200010;
const int M = 2e14 + 10;
const int mod = 1e9 + 7;
inline void solve() {
int n;
cin >> n;
int oo = 0;
vector<int>a(n + 1);
for (int i = 1; i <= n; i++) {
cin >> a[i];
oo ^= a[i];
}
int ans = oo;
for (int i = 1; i <= n; i++) {
for(int j=1;j<=n/i;j++){
int l=a[i]+j;
int r=a[i]*j;
ans=max(ans,oo^a[i]^l);
ans=max(ans,oo^a[i]^r);
}
}
cout<<ans<<"\n";
}
signed main() {
solve();
return 0;
}
G.旅途的终点
G-旅途的终点_河南萌新联赛2024第(一)场:河南农业大学 (nowcoder.com)
一开始没有看清楚题目,我以为是挑选城市去旅游,我就直接排序贪心,结果wa了。
后来才发现必须从1到n,所以需要使用一个优先队列去维护我们的最大值,当当前我们的体力不能支撑时,我们反悔之前使用的最大体力(前提是有神力次数,不然就直接输出当前遍历的位置-1)。
#include<bits/stdc++.h>
#define int long long
#define TEST int T;cin>>T;while(T--)
#define lowbit(x) x&(-x)
using namespace std;
const int N = 200010;
const int M = 2e14 + 10;
const int mod = 1e9 + 7;
inline void solve() {
int n,c,k;
cin>>n>>c>>k;
vector<int>a(n+1);
priority_queue<int>q;
for(int i=1;i<=n;i++) cin>>a[i];
int ans=0;
for(int i=1;i<=n;i++)
{
c-=a[i];
q.push(a[i]);
if(c<=0)
{
if(k==0)
{
cout<<i-1<<"\n";
return;
}
c+=q.top();
k--;
q.pop();
}
}
cout<<n<<"\n";
}
signed main() {
solve();
return 0;
}
H.两难抉择
H-两难抉择_河南萌新联赛2024第(一)场:河南农业大学 (nowcoder.com)
我们可以贪心一下。
发现当x或者ai为1时,相乘不如相加,反之相乘一直都是最优的。
#include<bits/stdc++.h>
#define int long long
#define TEST int T;cin>>T;while(T--)
#define lowbit(x) x&(-x)
using namespace std;
const int N = 200010;
const int M = 2e14 + 10;
const int mod = 1e9 + 7;
inline void solve() {
int n;
cin>>n;
int mx=-1,mi=1e9,sum=0;
for(int i=1,x;i<=n;i++)
{
cin>>x;
sum+=x;
mx=max(mx,x);
mi=min(mi,x);
}
if(n==1||mx==1)
{
cout<<sum+n<<"\n";
return;
}
cout<<(sum-mx)+mx*n<<"\n";
}
signed main() {
solve();
return 0;
}
I.除法移位
I-除法移位_河南萌新联赛2024第(一)场:河南农业大学 (nowcoder.com)
这个题目也是贪心,因为是S最大,而且S最大的要求是必须左边第一个元素必须是我们可以做到的最大值。
#include<bits/stdc++.h>
#define int long long
#define TEST int T;cin>>T;while(T--)
#define lowbit(x) x&(-x)
using namespace std;
const int N = 200010;
const int M = 2e14 + 10;
const int mod = 1e9 + 7;
int a[N];
inline void solve() {
int n,t;
cin>>n>>t;
int mx=-1;
for(int i=1;i<=n;i++) cin>>a[i],mx=max(mx,a[i]);
if(a[1]==mx){ cout<<"0\n";return ;}
mx=-1;
int ans;
for(int i=n;i>=max(1ll,n-t+1);i--)
{
if(a[i]>mx)
{
mx=a[i];
ans=(n-i)+1;
}
}
cout<<ans<<"\n";
}
signed main() {
solve();
return 0;
}
K.图上计数(Easy)
K-图上计数(Easy)_河南萌新联赛2024第(一)场:河南农业大学 (nowcoder.com)
贪心~
考虑n<=1是只能分成两部分,反之将n分成相近的两部分直接相乘,这样的乘积最大(基本不等式)。
#include<bits/stdc++.h>
#define int long long
#define TEST int T;cin>>T;while(T--)
#define lowbit(x) x&(-x)
using namespace std;
const int N = 200010;
const int M = 2e14 + 10;
const int mod = 1e9 + 7;
inline void solve() {
int n,m;
cin>>n>>m;
for(int i=1;i<=m;i++)
{
int u,v;
cin>>u>>v;
}
if(n<=1)
{
cout<<"0\n";
}
else
{
cout<<(n/2*(n-n/2))<<"\n";
}
}
signed main() {
solve();
return 0;
}