首页 > 其他分享 >NOIP模拟1

NOIP模拟1

时间:2024-07-09 10:34:10浏览次数:18  
标签:NOIP int namespace long freopen using 模拟 define

赛时rank3,95,30,40,5,5

赛后hack,rank7,40,30,40,5,5

\(太CAI了\)

T1 分糖果

简要题意:
将\(n\)个数分成最多组,使得每组有\(3\)个人,每组的数字和能被\(3\)整除,输出组数和方案

\(n≤10^5,1≤a_i≤10^5\)

\(solution:\)

将每个数\(\mod3\)存入,则有三类:余数为0,1,2;

可以的方案有三种\(0,0,0\),\(0,1,2\),\(1,1,1\),\(2,2,2\)

考虑到\(0,1,2\)不少于三个时无意义,所以枚举\(0,1,2\)的个数,时间复杂度\(O(n)\)

\(code:\)

点此查看代码
#include<bits/stdc++.h>
#include<bits/extc++.h>
// using namespace __gnu_pbds;
// using namespace __gnu_cxx;
using namespace std;
#define infile(x) freopen(x,"r",stdin)
#define outfile(x) freopen(x,"w",stdout)
#define errfile(x) freopen(x,"w",stderr)
using ll=long long;using ull=unsigned long long;
const int N = 1e5 + 10;
int n,a[N];
queue<int> tot[3];
signed main(){
    #ifndef ONLINE_JUDGE
        infile("in.in");outfile("out.out");
    #else
    #endif
    cin.tie(0)->sync_with_stdio(false);
    cout.tie(0)->sync_with_stdio(false);
    cin>>n;
    for(int i = 1;i <= n; ++i) cin>>a[i];
    for(int i = 1;i <= n; ++i) tot[a[i]%3].push(i);
    int emm = min({tot[0].size(),tot[1].size(),tot[2].size()});
    ll ans = 0,res = 0;
    for(int i = 0;i <= min(emm,2); ++i){
        if(ans < (tot[0].size()-i)/3+(tot[1].size()-i)/3+(tot[2].size()-i)/3+i){
            ans = (tot[0].size()-i)/3+(tot[1].size()-i)/3+(tot[2].size()-i)/3+i;
            res = i;
        }
    }
    cout<<ans<<'\n';
    if(!ans) return 0;
    while(res--){
        cout<<tot[0].front()<<' '<<tot[1].front()<<' '<<tot[2].front()<<'\n';
        tot[0].pop();tot[1].pop();tot[2].pop();
    }
    while(tot[0].size()>=3){
        cout<<tot[0].front()<<' ';tot[0].pop();
        cout<<tot[0].front()<<' ';tot[0].pop();
        cout<<tot[0].front()<<'\n';tot[0].pop();
    }
    while(tot[1].size()>=3){
        cout<<tot[1].front()<<' ';tot[1].pop();
        cout<<tot[1].front()<<' ';tot[1].pop();
        cout<<tot[1].front()<<'\n';tot[1].pop();
    }
    while(tot[2].size()>=3){
        cout<<tot[2].front()<<' ';tot[2].pop();
        cout<<tot[2].front()<<' ';tot[2].pop();
        cout<<tot[2].front()<<'\n';tot[2].pop();
    }
}

T2 乒乓球

找循环节,不会打,待填

T3 与或

简要题意:

给定一个长度为\(n\)的数组\(a\,\)\((n\le 10^5)\),和\(k\)个|运算符,\(n-k-1\)个&运算符,用以上\(n-1\)个符号将数组连接起来,从左到右计算结果,使得结果最大并且符号序列的字典序最小,输出结果和符号序列。

样例输入1

4 2
1 3 5 7

样例输出1

7
||&

样例输入2

4 1
1 3 5 7

样例输出2

7
&&|

\(solution:\)

有一个结论:&放在|前一定不劣。

证明:假设有三个相邻的位置x,y,z,左边是,右边是&,那么结果最大是z,假设左边是&,右边是,那么结果最小是z

考虑按位贪心,对于当前位置,若放了|后后续最大答案仍是理论最大值,则放|,反之,则放&

\(code:\)

点此查看代码
#include<bits/stdc++.h>
#include<bits/extc++.h>
// using namespace __gnu_pbds;
// using namespace __gnu_cxx;
using namespace std;
#define infile(x) freopen(x,"r",stdin)
#define outfile(x) freopen(x,"w",stdout)
#define errfile(x) freopen(x,"w",stderr)
using ll=long long;using ull=unsigned long long;
const int N = 2e5 + 10;
int n,k,sum[N][61];
ll a[N];
inline ll check(int pos,ll val,int k){
    if(pos <= n - k){
        vector<int> t(60);
        for(int i = 0;i < 60; ++i)
            t[i] = sum[n-k][i] - sum[pos-1][i];
        for(int i = 0;i < 60; ++i)
            if(t[i] != (n-k-pos+1) && ((val>>i)&1))
                val ^= (1ll<<i);
    }
    if(k >= 1){
        vector<int> t(60);
        for(int i = 0;i < 60; ++i) t[i] = sum[n][i] - sum[n - k][i];
        for(int i = 0;i < 60; ++i) if(t[i]) val |= (1ll<<i);
    }
    return val;
}
signed main(){
    #ifdef ONLINE_JUDGE
        infile("in.in");outfile("out.out");
    #else
    #endif
    cin.tie(0)->sync_with_stdio(false);
    cout.tie(0)->sync_with_stdio(false);
    cin>>n>>k;
    for(int i = 1;i <= n; ++i) cin >> a[i];
    for(int i = 1;i <= n; ++i){
        for(int j = 0;j < 60; ++j) sum[i][j] = sum[i-1][j];
        for(int j = 0;j < 60; ++j) sum[i][j] += ((a[i]>>j)&1);
    }
    ll mx = check(2,a[1],k);
    cout<<mx<<'\n';
    int nowk = k;ll ans = 1;
    for(int i = 2;i <= n; ++i){
        if(nowk >= 1 && check(i+1,ans|a[i],nowk-1) == mx){
            cout<<'|';
            ans |= a[i];
            nowk--;
        }
        else cout<<'&',ans &= a[i];
    }
}

T4 跳舞

\(solution:\)

用\(ok_{i,j}\)表示\(i\sim j\)可以消去,利用区间dp

\[ok_{i,j} = \max ok_{i,k-1}\& ok_{k+1,j}\&[gcd(a[i-1],a[k])>1\,||\, gcd(a[k],a[j+1])>1] \]

再考虑设\(f_i\)表示钦定留下第\(i\)个,可以删掉几个人

则有

\[f_i = \max f_j + ((i-j-1)\&ok_{j+1,i-1}) \]

注意处理ok的边界,\(ok_{i,i-1}=1\)

\(code:\)

点此查看代码
#include<bits/stdc++.h>
#include<bits/extc++.h>
// using namespace __gnu_pbds;
// using namespace __gnu_cxx;
using namespace std;
#define infile(x) freopen(x,"r",stdin)
#define outfile(x) freopen(x,"w",stdout)
#define errfile(x) freopen(x,"w",stderr)
using ll=long long;using ull=unsigned long long;
const int N = 510;
bitset<N> ok[N];
int n,a[N],f[N];
bitset<N> gcd[N];
signed main(){
    #ifndef ONLINE_JUDGE
        infile("in.in");outfile("out.out");
    #else
    #endif
    cin.tie(0)->sync_with_stdio(false);
    cout.tie(0)->sync_with_stdio(false);
    cin >> n;
    for(int i = 1;i <= n; ++i) cin >> a[i];
    for(int i = 1;i <= n; ++i)
        for(int j = 1;j <= n; ++j)
            gcd[i][j] = (__gcd(a[i],a[j])>1);
    for(int i = 1;i <= n; ++i)
        if(gcd[i][i-1] || gcd[i][i+1]) ok[i][i] = true;
    for(int i = 1;i <= n; ++i){
        for(int j = 1;j < i; ++j){
            ok[i][j] = true;
        }
    }
    for(int len = 2;len <= n; ++len){
        for(int i = 1;i + len - 1 <= n; ++i){
            int ed = i + len - 1;
            for(int j = i;j <= ed; ++j){
                if(ok[i][ed]) break;
                ok[i][ed] = (ok[i][j-1]&&ok[j+1][ed]&&(gcd[j][i-1]||gcd[j][ed+1]));
            }
        }
    }
    for(int i = 2;i <= n+1; ++i){
        for(int j = 0; j < i; ++j){
            f[i] = max(f[i],f[j]+(i-j-1)*ok[j+1][i-1]);
        }
    }
    cout<<f[n+1];
}

T5 音乐播放器

概率dp,不会……,待填

总结:
还是

\[CAI \]

标签:NOIP,int,namespace,long,freopen,using,模拟,define
From: https://www.cnblogs.com/hzoi-Cu/p/18290661

相关文章

  • 原生js简单模拟移动端下拉刷新
    <!DOCTYPEhtml><htmllang="en"><head><metacharset="UTF-8"><metaname="viewport"content="width=device-width,initial-scale=1.0"><title>Docu......
  • 手写简单模拟mvc
    目录结构: 两个注解类:@Controller:packagecom.heaboy.annotation;importjava.lang.annotation.*;/***注解没有功能只是简单标记*.RUNTIME运行时还能看到*.CLASS类里面还有,构建对象久没来了,这个说明是给类加载器的*.SOURCE表示这个注解能存活到......
  • P2239 [NOIP2014 普及组] 螺旋矩阵
    洛谷题面:题目分析本题需要一个旋转的数字矩阵,因为填数要求,首先考虑DFS。注意写题目时,一定一定要注意数据范围!在此题中,注意数据范围对于 50%的数据,1⩽......
  • YC311A [ 20240701 CQYC省选模拟赛 T1 ] 好串(good)
    题意给定一个长度为\(n\)的\(01\)串。定义一个串是好的当且仅当该串的所有前缀以及所有后缀的\(1\)的数量大于等于\(0\)的数量。你需要维护\(q\)个查询,每次求\(S_{l,...,r}\)的子串最少添加的\(1\)的个数使得该子串是好的。Sol首先不难发现一个正确的贪心,也......
  • 题解:洛谷 P2678 [NOIP2015 提高组] 跳石头
    题解:洛谷P2678[NOIP2015提高组]跳石头标签:二分,贪心题意给定一个数列,\(a_0=0,a_{N+1}=L\),从其中删除不超过\(M\)个数,使得\(a_i-a_{i-1}\)的最小值最大。思路从最小值最大不难想到二分答案。统计\(a_i-a_j<mid\)的数量\(k\),如果不满足的话说明不删,\(j\getsi\)。......
  • [NOIP2011 提高组] 聪明的质监员
    [NOIP2011提高组]聪明的质监员题目描述小T是一名质量监督员,最近负责检验一批矿产的质量。这批矿产共有\(n\)个矿石,从\(1\)到\(n\)逐一编号,每个矿石都有自己的重量\(w_i\)以及价值\(v_i\)。检验矿产的流程是:给定$m$个区间\([l_i,r_i]\);选出一个参数\(W\);对......
  • C语言之考勤模拟系统平台(千行代码)
    考勤模拟系统平台目录第一章软件需求分析...1第二章系统结构设计...32.1系统架构...32.2系统组件...32.3系统流程...3第三章数据结构设计...4第四章模块划分及各模块功能介绍...64.1用户模块(UserModule)...64.2组模块(GroupModule)...64.3打卡模块(Cloc......
  • P1068 [NOIP2009 普及组] 分数线划定【排序】
    [NOIP2009普及组]分数线划定题目描述世博会志愿者的选拔工作正在A市如火如荼的进行。为了选拔最合适的人才,A市对所有报名的选手进行了笔试,笔试分数达到面试分数线的选手方可进入面试。面试分数线根据计划录取人数的150......
  • 基于Matlab模拟城市环境中非地面网络(卫星/无人机)无线电信道
     ✅作者简介:热爱科研的Matlab仿真开发者,修心和技术同步精进,代码获取、论文复现及科研仿真合作可私信。......
  • Python和MATLAB微机电健康推导算法和系统模拟优化设计
    ......