0318-0324题解

成信大天梯赛

L1-6 二进制
因为二进制是逢二进一,所以我们只要用cnt记录一下每一位上的数并给它加起来,然后cnt%2便是其和这一位上的数,注意要从右往左开始

点击查看代码
#include<bits/stdc++.h>
using namespace std;

typedef pair<int,int> pii;


void solve()
{
   string a,b;
    cin>>a>>b;
    string res;
    int i=a.size()-1,j=b.size()-1;
    int cnt=0;
    while(i>=0||j>=0||cnt){//注意cnt这个条件
        cnt+=(i>=0)?a[i--]-'0':0;//别忘了i--,j--
        cnt+=(j>=0)?b[j--]-'0':0;
        res.push_back(cnt%2+'0');//这边记得加‘0’
        cnt/=2;//别忘了除2
    }
    reverse(res.begin(),res.end());
    cout<<res;
}



signed main()
{
    solve();
    
}

L1-8 堆积木
这一题是个好题,我们要学习一个思想,把一些可以舍弃的数据舍弃掉,比如在这一题里面,每一个积木只跟上一个积木有关系,所以我们只用一个数组格便可以代表一个塔,可以将上上个覆盖掉,同样是stl的模拟题,还是要多练多练,下列代码有详细的注解

点击查看代码
#include<bits/stdc++.h>
using namespace std;
#define int long long
void solve()
{
    //做这种题首先要思考用什么容器来模拟题意
    vector<int>ve;//一个存塔的数量
    vector<int>he;//一个存高度
    int n;
    cin>>n;
    while(n--)
    {
        int x;
        cin>>x;
        if(ve.size()==0){//如果没有塔就新建一个塔
            ve.push_back(x);
            he.push_back(1);
        }
        else{
            int pos=-1,minn=1e9;//pos用来实现位置的更新
            //有塔就遍历塔找符合的
            for(int j=0;j<ve.size();j++)
            {
                if(ve[j]>x){
                    int temp=ve[j]-x;
                    if(temp<minn)
                    {
                        pos=j;
                        minn=temp;
                    }
                    else if(temp==minn){//如果差值相同就放在最高的上面
                        if(he[j]>he[pos]){
                            pos=j;
                        }
                        
                    }
   
                }
  
            }
            
            if(pos==-1){// 没有找到
                ve.push_back(x);
                he.push_back(1);
            }
            else{//找到了直接覆盖这个塔顶,因为下一个状态只跟当前的这个有关
                ve[pos]=x;
                he[pos]++;
            }
            
        }
    }
    
    int ans=0;
    for(int i=0;i<ve.size();i++) ans=max(he[i],ans);
    cout<<ans<<" "<<ve.size()<<endl;
}



signed main()
{
    solve();
    
}

天梯赛训练

P2669 [NOIP2015 普及组] 金币
这确实是一道简单题,但是如果你没处理好,可能会很浪费你的时间,这题给了我一个启发,就是把平方的归为一部分,其他的再加上去

点击查看代码
#include<bits/stdc++.h>
using namespace std;
typedef pair<int,int> pii;
#define int long long

void solve()
{
   int n,sum=0,temp=1,cnt=1,last=0;
   cin>>n;  
   while(1)
   {
       if(cnt>n) break;
       sum+=temp*temp;
       temp++;
       last=cnt;
       cnt+=temp;
   }
    if(last!=n){
        sum+=(n-last)*temp;
    }
    cout<<sum;
}



signed main()
{
    solve();
    return 0;
}
点击查看代码
#include<iostream>
using namespace std;
int main()
{
	int a,b=0,c=1,i;//a为天数,b为金币,c为每天比原来每天多获得的金币数 
	cin>>a;
	for(i=1;i<=a;i++)
		a-=i,b+=c*c,c++;//金币每天加上c的2次方,天数当然要减i了
	cout<<b+a*c;//最后算上剩余的a乘加的最多一次的c
	return 0;
}

P7071 [CSP-J2020] 优秀的拆分
先打个表把2的1到24次方打印出来,然后一个数我们从2的24次方开始遍历,遇到比他小的第一个数我们就减掉然后跳出循环,然后变成一个新的数以后再找第一个比它小的数以此下去

点击查看代码
#include<bits/stdc++.h>
using namespace std;
typedef pair<int,int> pii;
#define int long long
char c[105][105];
int dx[]={-1,-1,0,1,1,1,0,-1},dy[]={0,1,1,1,0,-1,-1,-1};
int a[25],b[25][25];
void solve()
{
    for(int i=1;i<=24;i++) a[i]=(int)pow(2,i);

   int n;
   cin>>n;
   if(n%2==1) cout<<"-1";
   else{
       while(n>0)
       {
            for(int i=24;i>=1;i--){
                if(a[i]<=n){
                    cout<<a[i]<<" ";
                    n-=a[i];
                    break;
                }
            }
       }
   }
    
}

signed main()
{
    solve();
    return 0;
}

P2058 [NOIP2016 普及组] 海港
这一题我们用set来存国籍的种类,用map来存国籍的人数,用一个存放pii的优先队列(会按点的第一个值来自动排序)来存每次每个国籍加入的时间,当时间超过了86400的时候我们便把优先队列中的这个时间对应的国籍删掉,对应的map中的这个国籍人数也要减,当对头对应的map中的国籍的人数为1的时候,set就除去这个国籍

点击查看代码
#include<bits/stdc++.h>
using namespace std;
typedef pair<int,int> pii;
#define int long long
char c[105][105];
int dx[]={-1,-1,0,1,1,1,0,-1},dy[]={0,1,1,1,0,-1,-1,-1};
int a[25],b[25][25];
set<int> se;
 priority_queue<pii,vector<pii>,greater<pii> >q;
unordered_map<int,int>mp;
void solve()
{
    int n,m;
   
    cin>>n>>m;
    while(m--)
    {
        int x;
        cin>>x;
        q.push({n,x});
        mp[x]++;
        se.insert(x);
    }
    
    while(n-q.top().first>=86400)
    {
        auto k=q.top();
        q.pop();
        if(mp[k.second]==1) se.erase(k.second);
        mp[k.second]--;
    }
    cout<<se.size()<<endl;
    
    
}

signed main()
{
    int t;
    cin>>t;
    while(t--)solve();
    return 0;
}

专题训练

还没复盘完毕

posted on 2024-03-24 17:08  swj2529411658  阅读(38)  评论(0)    收藏  举报

导航