首页 > 其他分享 >洛谷 P4829 kry loves 2048——题解

洛谷 P4829 kry loves 2048——题解

时间:2024-09-07 19:02:45浏览次数:10  
标签:kry 洛谷 int 题解 ll 样例 seed Downarrow 方块

洛谷P4829题解


传送锚点


摸鱼环节

kry loves 2048

题目背景

kls是一个人赢。

题目描述

kls最近在玩一款类似2048的游戏,规则是这样的:

一开始,有\(n\)个方块,每个方块上有一个\(1\)到\(m\)的整数。

kls可以进行两种操作:

  1. 选择两个数字相同的方块(不一定要相邻),将它们合并成一个数字为原来的两倍的方块;

  2. 减小一个方块上的数字。

操作的次数没有限制,最终的得分为所有方块上的最大的数字。

因为kls要去陪妹子了,没有时间继续玩,他想让你帮忙计算一下,最多能得到多少分。

输入格式

因为数据可能很大,读入容易超时,所以kls给你们提供了一个c++的随机数生成器。

void generate_array(int a[], int n, int m, int seed) {
    unsigned x = seed;
    for (int i = 0; i < n; ++i) {
        x ^= x << 13;
        x ^= x >> 17;
        x ^= x << 5;
        a[i] = x % m + 1;
    }
}

把这个函数复制到你的程序里。用一个足够大的数组,以及输入数据给出的\(n\),\(m\)和\(seed\)作为参数,调用这个函数。然后这个数组里就是一开始的方块上的数字(下标从0开始)。

输入一行三个数\(n,m,seed\),含义如上。

输出格式

一行一个数,表示最大得分。

样例 #1

样例输入 #1

5 10 233

样例输出 #1

24

样例 #2

样例输入 #2

5 50 3

样例输出 #2

48

样例 #3

样例输入 #3

1000 1000 666

样例输出 #3

374784

提示

样例解释

样例1生成出来的数是 6 10 7 5 4。

样例2生成出来的数是 8 12 48 4 4。

数据范围

对于30%的数据,\(n, m \le 10\);

对于60%的数据,\(n, m \le 10^5\);

对于100%的数据,\(n, m \le 10^7\),\(1 \le seed \le 10^9\)。


众所周知,oier们喜欢处理一些奇奇怪怪非常有意思的问题。同时,oier们都乐于助人,每天都在帮不同的人处理不同的问题(我cow,今天这个人怎么还有妹子可以陪),面对kls的困难之处,咱们oier酸了当然得帮他解决。所以,正解是帮他陪妹子。


正片开始

1.草率代码

类似于合并果子,每次应该选取小于数\(a\)
中的最大值进行合并,考虑用优先队列维护。

code:

#include<bits/stdc++.h>
#define ll long long
using namespace std;
const ll N=1e7+5;
ll n,m,seed,ans;
ll a[N];
priority_queue<ll,vector<ll>,greater<ll> > q;//小数在前
void cao(ll n, ll m, ll seed) //n个数,m域 
{
    unsigned x=seed;
    for(ll i=0;i<n;++i) 
	{
        x^=x<<13;
        x^=x>>17;
        x^=x<<5;
        a[i]=x%m+1;
    }
}
int main()
{
    cin>>n>>m>>seed;
    cao(n,m,seed);
    for(int i=0;i<=n;i++) q.push(a[i]);
    while(q.size()>1)
    {
    	ll x=q.top(),y,z;
    	q.pop();
    	y=q.top();
    	q.pop();
    	z=2*x;
    	ans=max(ans,max(x,y));//更新当前答案
    	q.push(max(z,y));//比较是选择较小数*2更优,还是较大数更优。
	}
	ans=max(ans,q.top());
	cout<<ans;
    return 0;
}

然后突然发现,代码TLE,还T了4个点,看着黄色的60,内心万分不甘,于是打开题解区认真分析下复杂度。发现代码的复杂度为\(nlogn\),\(n=1e7\)显然是祭得很惨。

2.优化环节

很明显这个\(logn\)肯定是得去掉的,由于在排序上的复杂度不够优,所以选择用计数排序预处理解决问题,这样复杂度就降到了\(o(n)\),于是快乐AC了。

code:

for(int i=mina;i<=maxa;i++)
    for(int j=1;j<=t[i];j++)
        a[++len]=i;

完整代码

#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int N=1e7+5;
int n,m,seed,b[N],a[N],t[N];
ll maxa=0,mina=0x3f;
ll len=0,cnt=1;
queue<ll>q;
void cao(int n, int m, int seed) 
{
    unsigned x=seed;
    for(int i=1;i<=n;++i) 
	{
        x^=x<<13;
        x^=x>>17;
        x^=x<<5;
        b[i]=x%m+1;
    }
}
ll get()
{
    if(q.empty()) return a[cnt++];
    ll x=q.front();
    if(cnt==n+1||a[cnt]>x)
    {
        q.pop();
        return x;
    }
    return a[cnt++];
    
}
int main()
{
    cin>>n>>m>>seed;
    cao(n,m,seed);
    for(int i=1;i<=n;i++)
    {
        t[b[i]]++;
        maxa=max(maxa,1ll*b[i]);
        mina=min(mina,1ll*b[i]);
    }
    for(int i=mina;i<=maxa;i++)
        for(int j=1;j<=t[i];j++)
            a[++len]=i;//计数排序
    for(int i=1;i<n;i++)
    {
        ll x=get(),y=get();
        q.push(max(x*2,y));
    }
    cout<<q.front()<<endl;
    return 0;
}

完结收工!!!!!

个人主页

看完点赞,养成习惯

\(\Downarrow\Downarrow\Downarrow\Downarrow\Downarrow\Downarrow\Downarrow\Downarrow\Downarrow\Downarrow\Downarrow\Downarrow\Downarrow\Downarrow\Downarrow\Downarrow\Downarrow\Downarrow\Downarrow\Downarrow\Downarrow\Downarrow\Downarrow\Downarrow\Downarrow\)

标签:kry,洛谷,int,题解,ll,样例,seed,Downarrow,方块
From: https://www.cnblogs.com/qc0817/p/18402024

相关文章

  • 【题解】【动态规划】—— [NOIP2001 普及组] 装箱问题
    【题解】【动态规划】——[NOIP2001普及组]装箱问题[NOIP2001普及组]装箱问题题目描述输入格式输出格式输入输出样例输入#1输出#1提示1.题意解析2.AC代码2.1.二维d......
  • 【题解】—— [NOIP2005 普及组] 陶陶摘苹果
    【题解】——[NOIP2005普及组]陶陶摘苹果[NOIP2005普及组]陶陶摘苹果题目描述输入格式输出格式输入输出样例输入#1输出#1提示1.题意解析2.AC代码[NOIP2005普及组]陶陶摘苹果通往洛谷的传送门题目描述陶陶家的院子里有一棵苹果树,每到秋天树上就会结出......
  • 【题解】【结构体排序】——[NOIP2007 普及组] 奖学金
    【题解】【结构体排序】——[NOIP2007普及组]奖学金[NOIP2007普及组]奖学金题目背景题目描述输入格式输出格式输入输出样例输入#1输出#1输入#2输出#21.题意解析2.AC代码[NOIP2007普及组]奖学金通往洛谷的传送门题目背景NOIP2007普及组T1题目描述某......
  • 洛谷刷题之B2089 数组逆序重存放
    数组逆序重存放题目入口题目描述将一个数组中的值按逆序重新存放。例如,原来的顺序为8,6,5......
  • [ABC328G] Cut and Reorder 题解
    [ABC328G]CutandReorder题解题目不难,思维难度尚可。首先需要发现的性质是\(1\)操作的次数最多只需要使用一次,使用多少次其实都是等价的。\(n\le22\)显然考虑状压dp。平凡的想法是设\(dp_{i,j}\)表示填数的状态为\(i\),最后一个填的是\(j\)位置的数的最小代价。这......
  • CF1991F Triangle Formation 题解
    Description你有\(n\)根棍子,从\(1\)到\(n\)编号。第\(i\)根棍子的长度是\(a_i\)。你需要回答\(q\)个问题。在每个查询中,你会得到两个整数\(l\)和\(r\)(\(1\lel<r\len,r−l+1\ge6\))。确定是否可以从编号为\(l\)到\(r\)的棒中选择\(6\)个不同的棒,形......
  • [ABC293Ex] Optimal Path Decomposition 题解
    [ABC293Ex]OptimalPathDecomposition题解是一道难得一遇的好题。对于题目中的两个限制,同时满足是困难的,于是考虑常见的套路:先固定其中一个,再计算另一个。对于本题,显然\(k\)是有单调性的,于是考虑二分这个\(k\),将最优性问题转化为可行性问题,dp路径的最小长度。那么考虑d......
  • CF1991E Coloring Game 题解
    Description有一个由\(n\)个顶点和\(m\)条边组成的无向图。每个顶点可以用三种颜色之一着色:\(1\)、\(2\)或\(3\)。初始时,所有顶点都未着色。Alice和Bob正在玩一个包含\(n\)轮的游戏。在每一轮中,都会发生以下两个步骤:Alice选择两种不同的颜色。Bob选择一个未......
  • CF2009G. Yunli's Subarray Queries 题解
    G1题目要求,对于一个子区间$a_{l\siml+k-1}$,最少要进行多少次单点修改,才能使$\forall\l<i\leql+k-1,a_i=a_{i-1}+1$,其中$k$是固定的。对于这种问题,我们通常有一个trick:将$a_i$变为$a_i-i$。这样的话,我们要求的答案就变为了$k$减去变化后的$a_{l\siml+k-1}$......
  • RecyclerView 高效使用与常见问题解决
    RecyclerView是Android应用开发中最常用的UI组件之一,通常用于显示大量数据列表。尽管功能强大,但如果使用不当,会导致性能问题、数据错乱或滚动卡顿等问题。在本篇文章中,我们将探讨RecyclerView的一些常见坑点,提供解决方案,并附带代码示例。1.坑点:ViewHolder重用导致数据错乱......