洛谷 8 月月赛 & 「PMOI」Round · 04

T1 T166167 「PMOI-4」人赢#

题目大意#

给一个数列的前两项分别为nm
i3ai=ai1ai2的个位
给定n,m,k, 求以nm为前两项的数列的第k
(数据范围 0n,m9 1k1e12

思路#

通过观察样例可以发发现 n,m很小 k很大 因此这道题肯定是有规律的
通过打表我们可以发现 这个数列从第三项开始 每 六项 重复一次
因此我们可以通过找到数列的前六项来找到第k个数字是多少

AC_CODE#

#include <bits/stdc++.h>
#define x first    
#define y second    
//#define int long long 
#define endl '\n' 

using namespace std;
 
typedef pair<int, int> PII ;
typedef long long LL;

template < typename T >
inline void read(T &x)
{
    x = 0; bool f = 0; char ch = getchar();
    while(!isdigit(ch)){f ^= !(ch ^ 45);ch=getchar();}
    while(isdigit(ch)) x= (x<<1)+(x<<3)+(ch&15),ch=getchar();
    x = f ? -x : x;
}
const int N = 2e5 + 10;
int a[N];
void solve() {
    int n, k;
    read(n), read(k);
    LL ans = 0;
    for(int i = 1; i <= n; i ++ ) {
        read(a[i]);
        ans += a[i];
    }
    sort(a + 1, a + 1 + n);
    int res = n - k;
    if(res >= 2)
        cout << a[(res + 1) / 2] << endl;
    else {
        if(res == 0) cout << 0 << endl;
        else if(res == 1) cout << ans << endl;
    }
}

signed main() 
{
    int T = 1;  scanf("%d",&T);
    while(T -- ) {
        solve();
    }
 
    return 0;
}

T2 「PMOI-4」生成树#

题意#

给定一个数组 a[] 我们每次取出这个数列中的一个数字放入新数组中
当这个数字在新数组中的下标为i 这个数字原本k时 其他的数字
加上1i+k+1k 求新数组中所有的数字最大的和

思路#

我们需要求所有的数字最大的和,基于贪心的思想,我们要让每个数字尽可能的大
当某个数字先选的时候 他会对后面的造成影响,因此我们要让这个影响尽可能的大
可以使后面的数字尽可能的大
由此add受到下标ik的 奇偶性问题 我们做出以下分析

  • 当我们填到第奇数个数字时 我们需要让它对后面的影响为正
    - i+k+1是奇数 且 k是负数
    - i+k+1是偶数 且 k是正数
    - |k| 尽可能的大(对后面的影响更大
    - 如果上述两种情况不存在,我们优先去放 0(0对后面无影响
    - 如果以上都不存在,我们只能放对后面造成负影响的数字,因此我们让它绝对值尽可能小
  • 偶数同上

AC_CODE#

#include <bits/stdc++.h>
#define x first    
#define y second    
#define pb push_back
#define mk make_pair
#define debug(x) cout<<#x" ----> "<<x<<endl
#define rep(i, b, s) for(int i = (b); i <= (s); ++i)
#define pre(i, b, s) for(int i = (b); i >= (s); --i)

//#define int long long 
#define endl '\n' 
#define ios ios::sync_with_stdio(false); cin.tie(0), cout.tie(0)
#define all(v) (v).begin(),(v).end()

using namespace std;
 
typedef unsigned long long ULL;
typedef pair<int, int> PII ;
typedef pair<double, double> PDD ;
typedef long long LL;

const int N = 1e5 + 10;
int n;
PII a[N];
int b[N];
bool cmp(PII p, PII q) {
    return abs(p.x) < abs(q.x);
}
void solve() {
    scanf("%d", &n);
    vector<PII> l, r;
    int cnt = 0;
    for(int i = 0; i < n; i ++ ) {
        int x;
        scanf("%d", &x);
        b[i] = x;
        if(!x) cnt ++;
        else if(x < 0 && x & 1 || x > 0 && !(x & 1)) l.pb({x, i});
        else r.pb({x, i});
    }
    sort(all(l), cmp);
    sort(all(r), cmp);
    int len1 = l.size(), len2 = r.size();
    int t1 = len1 - 1, t2 = len2 - 1, e1 = 0, e2 = 0;
    for(int i = 0; i < n; i ++ ) {
        if((i + 1) & 1) {
            if(t1 >= e1) {
                a[i] = l[t1 --];
            }
            else if(cnt) {
                a[i] = {0, 0};
                cnt --;
            }
            else a[i] = r[e2 ++]; 
        }
        else {
            if(t2 >= e2) a[i] = r[t2 -- ];
            else if(cnt) {
                a[i] = {0, 0};
                cnt --;
            }
            else a[i] = l[e1 ++];
        }
    }
    
    // for(int i = 0; i < n; i ++ ) 
    //     printf("%d %d\n", a[i].x, a[i].y);

    LL res = 0, ans = 0;
    int t = 1;
    for(int i = 0; i < n; i ++, t ^= 1 ) {
        if(a[i].x == 0) {
            ans += res;
            continue;
        }
        ans += (res + a[i].x);
        int p = b[a[i].y];
        if((t + 1 + p) % 2 == 0) res += p;
        else res -= p; 
    }
    printf("%lld", ans);
    
    
}

 
signed main() 
{
    int T = 1; //scanf("%d",&T);
 
    while(T -- ) {
        solve();
    }
 
    return 0;
}
posted @   ccz9729  阅读(143)  评论(0编辑  收藏  举报
编辑推荐:
· AI与.NET技术实操系列:基于图像分类模型对图像进行分类
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· 25岁的心里话
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现
点击右上角即可分享
微信分享提示
主题色彩