题解

简介: 合成大数字 (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;
}
目录
相关文章
|
6月前
Leetcode contests 93 题解
870. Advantage Shuffle 起始就是hdoj 1502田忌赛马,但要求的结果不一样而已。这里我用了个pair来记录B中每个数字对应的位置。
27 0
|
7月前
|
数据安全/隐私保护
[FlareOn6]Overlong 题解
[FlareOn6]Overlong 题解
41 0
|
7月前
|
数据安全/隐私保护
[UTCTF2020]babymips 题解
[UTCTF2020]babymips 题解
33 1
|
7月前
|
数据安全/隐私保护
CrackRTF 题解
CrackRTF 题解
19 0
|
7月前
NSSCTF doublegame题解
NSSCTF doublegame题解
23 0
|
7月前
|
数据安全/隐私保护
[FlareOn5]FLEGGO 题解
[FlareOn5]FLEGGO 题解
26 1
|
C语言 数据安全/隐私保护
easyre题解
easyre题解
100 0
easyre题解
|
算法
rsarsa题解
rsarsa题解
108 0
rsarsa题解