河南萌新联赛2024第(一)场:河南农业大学

造数
\(25-24-12-6-3-2-0\)
\(11-10-5-4-2-0\)
1.观察上面的例子可以发现,每个数如果是偶数直接除二,如果是奇数就减一,这样得到的次数最少

#include <bits/stdc++.h>
#define int long long
#define endl '\n'
using namespace std;
typedef pair<int,int> pii;
#define x first
#define y second
#define all(v) v.begin(),v.end()
int dx[]={0,1,-1,0};
int dy[]={-1,0,0,1};
int a[35];


void solve()
{
    int n;cin>>n;
    int res=0;
    while(n>2)
    {
       if(n%2!=0)
       {
           res++;
           n--;
           continue;//这个continue别忘了 不然res会多加一次
       }
       n/=2;
        res++;
    }
    if(n==2||n==1) res++;
    cout<<res;
}


signed main()
{
    ios::sync_with_stdio(0),cin.tie(0);
    int t=1;
    //cin>>t;
    while(t--) solve();
    return 0;
}

两难抉择
1.判断一下从大到小排序后的第一个元素,在操作1下大,还是操作2下大即可
2.但是别把操作中的x当成ve【0】了,x的范围是【1,n】,而不是【a1,an】

#include <bits/stdc++.h>
#define int long long
#define endl '\n'
using namespace std;
typedef pair<int,int> pii;
#define x first
#define y second
#define all(v) v.begin(),v.end()
#define allr(v) v.rbegin(),v.rend()
int dx[]={0,1,-1,0};
int dy[]={-1,0,0,1};
int a[35];


void solve()
{
    int n;cin>>n;
    int sum=0;
    vector<int>ve(n);
    int fla=0;
    for(int i=0;i<n;i++) {
        cin>>ve[i];
    }
    sort(allr(ve));
    if(ve[0]*n>(ve[0]+n)){
        ve[0]=ve[0]*n;
        
    }
    else ve[0]=ve[0]+n;
    for(int i=0;i<n;i++) sum+=ve[i];
    cout<<sum;
}


signed main()
{
    ios::sync_with_stdio(0),cin.tie(0);
    int t=1;
    //cin>>t;
    while(t--) solve();
    return 0;
}

图上计数(Easy)
1.直接算有几个顶点,然后这些顶点分为两部分乘积要最大,偶数则为(n/2)✖️(n/2),奇数则为(n/2)✖️(n/2+1)

void solve()
{
    int n,m;
    cin>>n>>m;
    int ans=0;
    while(m--)
    {
        int xx,yy;cin>>xx>>yy;
    }
    
    if(n&1) ans=(n/2)*(n/2+1);
    else ans=(n/2)*(n/2);
    cout<<ans;
    
}

除法移位
1.其实本质上也是个贪心,找能够移动的依次最大数即可,就是按从大到小找,尽量把大的往第一位挪即可
2.但是注意重复数这种情况,比如1 2 9 9 8,应该移动后面这个次数更少,当然这题是因为我的排序方式需要考虑这个
3.我是以点对的方式,x存值,y存位置,然后按照从大到小派,值相同按照序号从大到小排,然后按顺序遍历找满足条件的即可

#include <bits/stdc++.h>
#define int long long
#define endl '\n'
using namespace std;
typedef pair<int,int> pii;
#define x first
#define y second
#define all(v) v.begin(),v.end()
int dx[]={0,1,-1,0};
int dy[]={-1,0,0,1};
int a[35];
bool cmp(pii a,pii b)
{
    if(a.x!=b.x)return a.x>b.x;
     return a.y>b.y;
}
void solve()
{
    int n,m; cin>>n>>m;
    vector<pii>ve(n);
    for(int i=0;i<n;i++)
    {
        cin>>ve[i].x;
        ve[i].y=i;
    }
    sort(all(ve),cmp);
    int ans=0;
    if(ve[0].y==0){
        cout<<0;
        return;
    }
    for(int i=0;i<n;i++)
    {

            if(ve[i].y!=0&&n-ve[i].y<=m){
                ans=n-ve[i].y;
                break;
            }
    }
    //for(auto t:ve) cout<<t.x<<" "<<t.y<<endl;
    cout<<ans; 
    
}


signed main()
{
    ios::sync_with_stdio(0),cin.tie(0);
 
    int t=1;
    //cin>>t;
    while(t--) solve();
    return 0;
}

两难抉择新编
1.当n最大为2e5时,总的次数也才2472133,所以肯定满足暴力的条件
2.其次就是异或的一些小知识要知道,两个相同的数异或,相当于消除这个数

#include <bits/stdc++.h>
#define int long long
#define endl '\n'
using namespace std;
typedef pair<int,int> pii;
#define x first
#define y second
#define all(v) v.begin()+1,v.end()
int dx[]={0,1,-1,0};
int dy[]={-1,0,0,1};

void solve()
{
    int n; cin>>n;
    int sum=0;
    vector<int>ve(n+1);
    for(int i=0;i<n;i++)
    {
        cin>>ve[i];
        sum^=ve[i];
    }
    int ans=0;
    for(int i=1;i<=n;i++)
    {
        for(int j=1;j<=n/i;j++)
        {
            ans=max(ans,sum^ve[i-1]^(ve[i-1]+j));//两个相同的数异或为0相当于把a【i-1】转化为a【i-1】+j
            ans=max(ans,sum^ve[i-1]^(ve[i-1]*j));
        }
    }
    
    cout<<ans;
}


signed main()
{
    ios::sync_with_stdio(0),cin.tie(0);
    int t=1;
    //cin>>t;
    while(t--) solve();
    return 0;
}

旅途的终点
1.贪心的思想,用k次把耗费体力多的遍历掉,然后再检查遍历到多少个国家时sum>=m即可

#include <bits/stdc++.h>
#define int long long
#define endl '\n'
using namespace std;
typedef pair<int,int> pii;
#define x first
#define y second
#define all(v) v.begin(),v.end()
#define allr(v) v.rbegin(),v.rend()
int dx[]={0,1,-1,0};
int dy[]={-1,0,0,1};

void solve()
{
    int n,m,k; cin>>n>>m>>k;
    vector<int>ve(n);
    priority_queue<int,vector<int>,greater<int> >q;
    for(int i=0;i<n;i++){
        cin>>ve[i];
    }
    int sum=0;
    for(int i=0;i<n;i++)
    {
        q.push(ve[i]);
        if(q.size()>k)//因为队列是从小到大,当放的个数大于k个相当于这k个放到底部了
        {//所以当国家数少于k个时,直接遍历完输出n了
            sum+=q.top();
            q.pop();
        }
        if(sum>=m)
        {
            cout<<i;
            return;
        }
    }
     cout<<n;
}


signed main()
{
    ios::sync_with_stdio(0),cin.tie(0);
    int t=1;
    //cin>>t;
    while(t--) solve();
    return 0;
}

有大家喜欢的零食吗
1.典型的无权二分图最大匹配,只要把点存进去即可,注意从0开始存

#include <bits/stdc++.h>
#define int long long
#define endl '\n'
using namespace std;
typedef pair<int,int> pii;
#define x first
#define y second
#define all(v) v.begin(),v.end()

struct augment_path {
  vector<vector<int> > g;
  vector<int> pa;  // 匹配
  vector<int> pb;
  vector<int> vis;  // 访问
  int n, m;         // 两个点集中的顶点数量
  int dfn;          // 时间戳记
  int res;          // 匹配数

  augment_path(int _n, int _m) : n(_n), m(_m) {
    assert(0 <= n && 0 <= m);
    pa = vector<int>(n, -1);
    pb = vector<int>(m, -1);
    vis = vector<int>(n);
    g.resize(n);
    res = 0;
    dfn = 0;
  }

  void add(int from, int to) {
    assert(0 <= from && from < n && 0 <= to && to < m);
    g[from].push_back(to);
  }

  bool dfs(int v) {
    vis[v] = dfn;
    for (int u : g[v]) {
      if (pb[u] == -1) {
        pb[u] = v;
        pa[v] = u;
        return true;
      }
    }
    for (int u : g[v]) {
      if (vis[pb[u]] != dfn && dfs(pb[u])) {
        pa[v] = u;
        pb[u] = v;
        return true;
      }
    }
    return false;
  }

  int solve() {
    while (true) {
      dfn++;
      int cnt = 0;
      for (int i = 0; i < n; i++) {
        if (pa[i] == -1 && dfs(i)) {
          cnt++;
        }
      }
      if (cnt == 0) {
        break;
      }
      res += cnt;
    }
    return res;
  }
};

void solve()
{
    int n; cin>>n;
    augment_path ans(n,n);
    for(int i=0;i<n;i++)
    {
        int x; cin>>x;
        while(x--)
        {
            int ls; cin>>ls;
            ans.add(i,--ls);
        }
    }
    int res=ans.solve();
    if(res==n) cout<<"Yes";
    else{
        cout<<"No";
        cout<<endl<<n-ans.solve();
    }
    
    
}





signed main()
{
    ios::sync_with_stdio(0),cin.tie(0);
    int t=1;
    //cin>>t;
    while(t--) solve();
}

小蓝的二进制询问

posted on 2024-07-17 20:57  swj2529411658  阅读(9)  评论(0编辑  收藏  举报

导航