河南萌新联赛2024第(三)场:河南大学

唐完了这场,rank last one 

​​​​​​​B-正则表达式_河南萌新联赛2024第(三)场:河南大学 (nowcoder.com)

忘开同步流,wa两发,人才。。。。。

#include<bits/stdc++.h>
#define endl '\n'
#define mk make_pair
#define int long long
#define ll long long
using namespace std;
typedef pair<int, int> PII;
const int N = 2e5+7;
const int mod = 998244353;
int n,m,k,l;
int a[N];
int sum=0;

bool check(int x){
    if(x<0||x>=256) return 0;
    else return 1;
}

void sovle(){
    scanf("%d%*c%d%*c%d%*c%d%*c",&n,&m,&k,&l);
    if(check(n)&&check(m)&&check(k)&&check(l)) sum++;
}

signed main()
{	
    //ios::sync_with_stdio(false), cin.tie(0),cout.tie(0); 
    int t = 1;
    cin>>t;
    while (t--){
        sovle();
    }
    cout<<sum<<endl;
    return 0;
}

 C-Circle_河南萌新联赛2024第(三)场:河南大学 (nowcoder.com)

蒽,结论题,不会推,也不知道怎么那么多人能推出来

n个圆最多把平面分割成n*(n-1)+2个部分,n=0时为1

#include<bits/stdc++.h>
#define endl '\n'
#define mk make_pair
#define int long long
#define ll long long
using namespace std;
typedef pair<int, int> PII;
const int N = 2e5+7;
const int mod = 998244353;
int n,m,k,l;

void sovle(){
    cin>>n;
    if(!n) cout<<1<<' ';
    else cout<<n*(n-1)+2<<' ';
}

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

F-累加器_河南萌新联赛2024第(三)场:河南大学 (nowcoder.com)

对x进行y次加1操作,问每次操作后二进制位上有多少位置改变.      (x&-x) 得到最低位的1是多少

从x变为x+y的结果,实际上等于1-y的结果减去1-x的结果,O2e6预处理出前缀和,O1查询即可

按位拆分,单独对每一个二进制位考虑,假设在这一位上发生了进位,那么他的贡献就是其位置

所以每一个f数组的值就是前一个数加上最低位的1产生的贡献

#include<bits/stdc++.h>
#define endl '\n'
#define mk make_pair
#define int long long
#define ll long long
using namespace std;
typedef pair<int, int> PII;
const int N = 2e5+7;
const int mod = 1e9+7;
int n,m,k;
int c[2000007],d[2000007];

void sovle(){
    cin>>n>>m;cout<<d[n+m]-d[n]<<endl;
}

signed main()
{	
    ios::sync_with_stdio(false), cin.tie(0),cout.tie(0); 
    int t = 1;
    c[1]=1;
    for(int i=1;i<=20;i++){
        c[1<<i]=1+i;
    }
    for(int i=1;i<=2000000;i++) d[i]=d[i-1]+c[i&-i];
    cin>>t;
    while (t--){
        sovle();
    }

    return 0;
}

H-魔法_河南萌新联赛2024第(三)场:河南大学 (nowcoder.com)

小白在一个n*m的迷宫中,起点为1.1,只能向右或者向下走,每个位置都有一个权值,走到该位置需要扣除这个权值的生命值,若走到n*m的位置生命值小于等于0就是失败,期间可以使用任意次魔法使得本次移动不扣除生命值,问最少使用多少次魔法能胜利走到n*m。

考虑一个三维dp,走到i,j这个位置使用k次魔法扣除的最少生命值。

#include <bits/stdc++.h>

using namespace std;
 
using i64 = long long;
 
const int N = 100010;
const i64 inf = 1e16;

signed main() {
  cin.tie(0)->sync_with_stdio(false);
  int n, m, h;
  cin >> n >> m >> h;
  vector a(n + 1, vector(m + 1, 0));
  for (int i = 1; i <= n; i++) {
    for (int j = 1; j <= m; j++) {
      cin >> a[i][j];
    }
  }
  vector dp(n + 1, vector(m + 1, vector(n + m, inf)));
  dp[1][1][1] = 0, dp[1][1][0] = 0;
  for (int i = 1; i <= n; i++) {
    for (int j = 1; j <= m; j++) {
      if (i == 1 && j == 1) continue;
      for (int k = 0; k < n + m; k++) {
        dp[i][j][k] = min(dp[i][j][k], dp[i - 1][j][k] + a[i][j]);
        dp[i][j][k] = min(dp[i][j][k], dp[i][j - 1][k] + a[i][j]);
        if (k) {
          dp[i][j][k] = min(dp[i][j][k], dp[i - 1][j][k - 1]);
          dp[i][j][k] = min(dp[i][j][k], dp[i][j - 1][k - 1]);
        }
      }
    }
  }
  for (int i = 0; i < n + m; i++) {
    if (dp[n][m][i] < h) {
      cout << i;
      return 0;
    }
  }
  return 0; 
}

 I-游戏_河南萌新联赛2024第(三)场:河南大学 (nowcoder.com)

很怪,链式前向星存图TLE,换成邻接表就过了

很容易看出,只有从1到n或者1到k再从k到n这两个情况

#include<bits/stdc++.h>
#define endl '\n'
#define mk make_pair
#define int long long
using namespace std;
typedef pair<int, int> PII;
const int N = 2e5+10;
const int mod = 998244353;
int n,m,k,l,u,v,w,cnt,z;
int a[N];
int d1[N];
int d2[N];
bool vis[N];

struct node{
    int v,w,z;
};
vector<node>x[N];

void dijkstra1(int c){
    d1[c]=0;
    priority_queue<PII,vector<PII>,greater<PII> >q;
    q.push({0,c});
    memset(vis,0,sizeof(vis));
    while(q.size()){
        auto u=q.top();q.pop();
        if(vis[u.second]) continue;
        vis[u.second]=1;
        for(auto ed:x[u.second]){
            if(ed.z==0) continue;
            if(d1[u.second]+ed.w<d1[ed.v]){
                d1[ed.v]=d1[u.second]+ed.w;
                q.push({d1[ed.v],ed.v});
            }
        }
    }
}

void dijkstra2(int c){
    d2[c]=0;
    priority_queue<PII,vector<PII>,greater<PII> >q;
    q.push({0,c});
    memset(vis,0,sizeof(vis));
    while(q.size()){
        auto u=q.top();q.pop();
        if(vis[u.second]) continue;
        vis[u.second]=1;
        for(auto ed:x[u.second]){
            if(d2[u.second]+ed.w<d2[ed.v]){
                d2[ed.v]=d2[u.second]+ed.w;
                q.push({d2[ed.v],ed.v});
            }
        }
    }
}

void sovle(){
    cin>>n>>m>>k;
    for(int i=1;i<=n;i++){
        d1[i]=LLONG_MAX;
        d2[i]=LLONG_MAX;
    }
    for(int i=1;i<=m;i++){
        cin>>u>>v>>w>>z;
        x[u].push_back({v,w,z});
        x[v].push_back({u,w,z});
    }
    dijkstra1(1);
    dijkstra2(k);
    if(d1[n]==LLONG_MAX&&d2[n]==LLONG_MAX||d1[n]==LLONG_MAX&&d1[k]==LLONG_MAX) cout<<-1<<endl;
    else cout<<min(d1[n],d1[k]+d2[n])<<endl;
}

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

    return 0;
}

  • 5
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值