题解

简介: 合成大数字 (vector模拟)  

题目描述
小码哥最近对小游戏很感兴趣,于是他仿照着合成大西瓜小游戏做了一个简化版程序。
在这个程序中游戏的区域变为了一维(即一条直线)。游戏内有n次投放格子的机会,每次机会程序会给出一个有着随机数R的新格子供小码哥投放。
一开始游戏内是空的(无格子),当游戏内无格子的时候,小码哥只能把新格子投放到第一个位置(最左边)﹔当游戏内有格子时,小码哥只能将新格子投放到某个已存在的格子上(称为被碰撞格子),并且如果被碰撞格子里的数字与新格子的数字相同,那么被碰撞格子里的数字会与新格子的数字合并,被碰撞的格子的数字也变成原来的2倍,这被称为一次合并,如果被碰撞格子里的数字与新格子的数字不同,那么新格子会插入到被碰撞格子的右侧。
除了上面的方式能触发合并以外,程序在每次投放后还会从左往右进行一次结算,如果相邻的两个格子的数字相同,那么这两个格子会合并成一个并且合并得到的格子的数字为原本两个格子的数字之和,并且右边的所有格子会向左移动来补齐空位(如果连续n个相同(n>2)先结算前两个),然后重新从左到右结算,这是合并的另—种触发方式
每当合并触发后,如果生成的格子内的数大于2048,那么这个格子会立即消失(消失优先度最高),空位由右边的所有格子向左移动来补齐,这被称为一次完美的合并。

小码哥还设计了一个得分系统:

1.每当他投放一个新数字或者触发一次合并,则得到等于新数字的得分或者等于合并生成的新数的得分,两者分开计算,即投入新数字时得到得分(无论是否触发合并),投入后并触发合并再追加获得合并的得分(另外,虽然完美的合并后格子会立即消失,但得分会计入)
⒉.程序会记录达成完美的合并的次数,初始次数为0,每当完成一次完美的合并次数+1
由于小码哥做这个程序时得分的显示区域有限,因此小码哥的得分系统里的得分显示的是总得分对10007取模得到的数字
现在给出投放机会的次数n,以及每次投放的数字R和小码哥投放的位置l,请你求出投放次数用完后游戏界面的情况(即格子的情况)以及小码哥最后的得分对10007取模得到的结果和小码哥达成完美的合并的次数。

输入格式
第一行一个正整数n,表示小码哥的投放次数
接下来n行每行两个数字R,l,表示新格子的数字和小码哥投放的位置

输出格式
第一行若干个正整数,表示最后游戏界面的情况,如果无输出也要换行
第二行两个整数,表示小码哥的得分对10007取模的结果和完成完美的合并的次数

输入样例
5
8 1
8 1
4 1
2 1
8 3
输出样例
16 2 4 8
46 0
分析
合成大西瓜的关键就在于如何在特定位置插入一个数字和删除一个数字。
需要用到vectorvector容器的insert(pos,num)insert(pos,num)函数和erase(vector.begin()+pos)erase(vector.begin()+pos)函数。

C++ 代码

#include<bits/stdc++.h>
using namespace std;
//计算分值
int cal(int n1,int n2)
{
    return (n1+n2)%10007;
}
int n;
int main()
{
    int score=0,perfect=0;
    vector<int> a;
    cin>>n;
    for(int i=0;i<n;i++)
    {
        int num,idx;
        cin>>num>>idx;
        score=cal(score,num);
        idx-=1;
        //一开始数组为空,直接插入一个元素
        if(a.size()==0)
            a.push_back(num);
        else{
            //如果插入的位置上的数和该数字相同,则合并
            if(a[idx]==num)
            {
                a[idx]*=2;
                score=cal(score,a[idx]);
                //如果大于2048,则为一次完美合并
                if(a[idx]>2048)
                {
                    perfect+=1;
                    //如果此时数组大小为1,删除该元素后数组为空
                    if(a.size()==1)
                        a.clear();
                    else{
                        //将该位置从vector中删除
                        a.erase(a.begin()+idx);  
                    }
                }

}
            else //a[idx]上有元素,且与插入的元素不等,就在右边插入
                a.insert(a.begin()+idx+1,num);
        }
        if(a.size()>1) //如果数组大小大于1,进行从左到右的删除操作
        {
            while(1){
                int ff=0;
                for(int j=0;j<a.size()-1;j++)
                {
                    //找到相邻两个相同的元素,就合并
                    if(a[j]==a[j+1])
                    {
                        a[j]*=2;
                        score=cal(score,a[j]);
                        ff=1;
                        //2个元素合并,删除一个元素
                        a.erase(a.begin()+j+1);
                        //完美操作
                        if(a[j]>2048)
                        {
                            perfect+=1;
                            if(a.size()==1) a.clear();
                            else a.erase(a.begin()+j); //该元素大于2048自动消除                        
                        }
                        break;                    
                    }
                }
                //没有相邻相同的元素,直接跳出
                if(ff==0)
                    break; 
            }            
        }
    }
    
    //输出结果
    for(auto item: a)    
        cout<<item<<" ";
    puts("");
    cout<<score%10007<<" "<<perfect;
    return 0;
}
目录
相关文章
|
7月前
leetcode-475:供暖器
leetcode-475:供暖器
52 0
|
7月前
|
消息中间件 Kubernetes NoSQL
LeetCode 3、28、1351
LeetCode 3、28、1351
LeetCode 354. Russian Doll Envelopes
给定一些标记了宽度和高度的信封,宽度和高度以整数对形式 (w, h) 出现。当另一个信封的宽度和高度都比这个信封大的时候,这个信封就可以放进另一个信封里,如同俄罗斯套娃一样。 请计算最多能有多少个信封能组成一组“俄罗斯套娃”信封(即可以把一个信封放到另一个信封里面)。
83 0
LeetCode 354. Russian Doll Envelopes
|
存储 Python
LeetCode 66. Plus One
给定表示非负整数的非空数字数组,加上整数的1。 存储数字使得最高有效数字位于列表的开头,并且数组中的每个元素包含单个数字。 您可以假设整数不包含任何前导零,除了数字0本身。
94 0
LeetCode 66. Plus One
leetcode 283 移动零
leetcode 283 移动零
58 0
|
存储
leetcode第57题
和上一道可以说是一个问题,只不过这个是给一个已经合并好的列表,然后给一个新的节点依据规则加入到合并好的列表。 解法一 对应 56 题的解法一,没看的话,可以先过去看一下。这个问题其实就是我们解法中的一个子问题没看的话,可以先过去看一下。这个问题其实就是我们解法中的一个子问题, 所以直接加过来就行了
107 0
leetcode第57题
leetcode第46题
这是自己开始想到的一个方法,考虑的思路是,先考虑小问题怎么解决,然后再利用小问题去解决大问题。没错,就是递归的思路。比如说, 如果只有 1 个数字 [ 1 ],那么很简单,直接返回 [ [ 1 ] ] 就 OK 了。 如果加了 1 个数字 2, [ 1 2 ] 该怎么办呢?我们只需要在上边的情况里,在 1 的空隙,也就是左边右边插入 2 就够了。变成 [ [ 2 1 ], [ 1 2 ] ]。
leetcode第46题
leetcode第44题
时间复杂度:text 长度是 T,pattern 长度是 P,那么就是 O(TP)。 空间复杂度:O(TP)。 同样的,和第10题一样,可以优化空间复杂度。
leetcode第44题
|
存储 算法
leetcode第43题
个位乘个位,得出一个数,然后个位乘十位,全部乘完以后,就再用十位乘以各个位。然后百位乘以各个位,最后将每次得出的数相加。十位的结果要补 1 个 0 ,百位的结果要补两个 0 。相加的话我们可以直接用之前的大数相加。直接看代码吧。
leetcode第43题
|
人工智能 算法
leetcode第41题
对于这种要求空间复杂度的,我们可以先考虑如果有一个等大的空间,我们可以怎么做。然后再考虑如果直接用原数组怎么做,主要是要保证数组的信息不要丢失。目前遇到的,主要有两种方法就是交换和取相反数。
leetcode第41题