开学第3周训练(天梯)

训练赛

天梯赛训练 - Virtual Judge (vjudge.net)

题解:比较🍬的题,需要我们统计24小时内船只上一共有多少个不同国的人

相当于暴力思想,我们直接开一个map记录每个国人数情况,然后算一下时间状态,用双指针然后前面超过24小时的就直接记录个数减减即可

#include <bits/stdc++.h>
//#pragma GCC optimize("Ofast")
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <queue>
#include <cmath>
//#define double long double
#define int long long
#define endl '\n'
using namespace std;
const int N=1e5+10,M=1e1;
const int INF = 0x3f3f3f3f;
const int mod=1e9+7;
typedef pair<int,int> PII;
int kmp(int a,int k,int p)
{
    int ans=1;
    while (k)
    {
        if(k&1) ans=ans*a%p;
        k>>=1;
        a=a*a;
    }
    return ans;
}


struct G
{
    int t,k;
}a[N];
vector< int> b[N];
map<int,int> mp;
void solve()
{
    int n;
    cin>>n;
    int ans=0;
    int l=1;
    for(int i=1;i<=n;i++)
    {
        int t,k;
        cin>>t>>k;
        a[i]={t,k};
        for(int j=1;j<=k;j++)
        {
            int x;
            cin>>x;
            b[i].push_back(x);
            mp[x]++;
            if(mp[x]==1) ans++;
        }
        while (a[i].t-a[l].t>=86400) {
            for (auto x: b[l]) {
                mp[x]--;
                if (mp[x] == 0) ans--;
            }
            l++;
        }

        cout<<ans<<endl;
    }
}
signed main(){
    std::ios::sync_with_stdio(false);
    std::cin.tie(nullptr);
    int T=1;
//    cin>>T;
    while(T--){
        solve();
    }
    return 0;
}

 天梯赛训练 - Virtual Judge (vjudge.net)

洛谷p5657

 题解:我们可以倒着去思考

看看规律我们可以发现,在n的次幂里有pow(2,n)个数,pow(2,n)/2    左边的数全是通过加0,右边的数是加一

所以我们从最后开始推断,k如果大于pow(2,n)/2 那么这一位就是加一,如果小于或者等于那就是加0   一位一位向上推

这里就需要更新这个k看看下面一个是由上面哪一个推出来的

画图发现

如果是右边就是pow(2,n)-1-k   就是上一个坐标位置   如果在左边那就是原来的k不动

比如n==3,k==5  那么n==2的时候就是pow(2,3)-1-5==2  也就是上一个的坐标   以此类推

记得开--int128   2的64太大

#include <bits/stdc++.h>
//#pragma GCC optimize("Ofast")
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <queue>
#include <cmath>
//#define double long double
#define int long long
#define endl '\n'
using namespace std;
const int N=1e5+10,M=1e1;
const int INF = 0x3f3f3f3f;
const int mod=1e9+7;
typedef pair<int,int> PII;
int kmp(int a,int k,int p)
{
    int ans=1;
    while (k)
    {
        if(k&1) ans=ans*a%p;
        k>>=1;
        a=a*a;
    }
    return ans;
}



void solve()
{
    int n,k;
    cin>>n>>k;
    string s;
    for(int i=n;i>=1;i--)
    {
        int x=((__int128)1<<i)-1;
        if(k>x/2)
        {
            s+='1';
            k=x-k;
        }
        else
        {
            s+='0';
        }
    }
    cout<<s<<endl;
}
signed main(){
    std::ios::sync_with_stdio(false);
    std::cin.tie(nullptr);
    int T=1;
//    cin>>T;
    while(T--){
        solve();
    }
    return 0;
}

 天梯赛训练 - Virtual Judge (vjudge.net)

题解:

不满分写法:优先队列实现,复杂度还是大了,我们直接自己写一个重构函数使用优先队列每一次都排个序就行了(60)

#include <bits/stdc++.h>
//#pragma GCC optimize("Ofast")
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <queue>
#include <cmath>
//#define double long double
#define int long long
#define endl '\n'
using namespace std;
const int N=6e6+10,M=1e1;
const int INF = 0x3f3f3f3f;
const int mod=1e9+7;
typedef pair<int,int> PII;
int kmp(int a,int k,int p)
{
int ans=1;
while (k)
{
if(k&1) ans=ans*a%p;
k>>=1;
a=a*a;
}
return ans;
}

struct G
{
int s,w;
int id;
}a[N];
class cmp{
public:
bool operator() (G& x,G& y)
{
if(x.s==y.s) return x.id>y.id;
return x.s<y.s;
}
};
priority_queue<G,vector<G>,cmp> mp;
bool cmp1(G x,G y)
{
if(x.s==y.s) return x.id<y.id;
return x.s>y.s;
}
void solve()
{
int n,r,q;
cin>>n>>r>>q;
priority_queue<G,vector<G>,cmp> mq;
for(int i=1;i<=n*2;i++)
{
int s;
cin>>s;
a[i].s=s;
}
for(int i=1;i<=n*2;i++)
{
int w;
cin>>w;
a[i].w=w;
a[i].id=i;
}
sort(a+1,a+1+n*2,cmp1);
for(int i=1;i<=n*2;i+=2)
{
if(a[i].w>a[i+1].w)
{
a[i].s+=1;
}
else
{
a[i+1].s+=1;
}
mq.push(a[i]);
mq.push(a[i+1]);
}
r--;
while (r--)
{

while (mq.size())
{
G x=mq.top();
mq.pop();
G y=mq.top();
mq.pop();
if(x.w>y.w)
{
x.s+=1;
}
else
{
y.s+=1;
}
mp.push(x);
mp.push(y);
}
mq=mp;
while (mp.size())
{
mp.pop();
}
}
G k;
for(int i=1;i<=n*2;i++)
{
if(i==q)
{
k=mq.top();
}

mq.pop();
}
cout<<k.id<<endl;
}
signed main(){
std::ios::sync_with_stdio(false);
std::cin.tie(nullptr);
int T=1;
// cin>>T;
while(T--){
solve();
}
return 0;
}

满分写法:

这里可能用到了归并排序的思想,我们可以利用sort里的merge函数实现

函数介绍:merge可以把两个有序数组合成一个有序数组,比如。 a=1 3 5  b=2  4.  然后放入函数开个新数组然后出c = 1 2 3 4 5 merge(a,a+3,b,b+2,c+1)

所以我们开两个数组一个win一个loser分别放进数组即可然后后面在合起来即可以了

注意这里我写了个结构体的内置排序方法可以当板子

#include <bits/stdc++.h>
//#pragma GCC optimize("Ofast")
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <queue>
#include <cmath>
//#define double long double
#define int long long
#define endl '\n'
using namespace std;
const int N=6e6+10,M=1e1;
const int INF = 0x3f3f3f3f;
const int mod=1e9+7;
typedef pair<int,int> PII;
int kmp(int a,int k,int p)
{
    int ans=1;
    while (k)
    {
        if(k&1) ans=ans*a%p;
        k>>=1;
        a=a*a;
    }
    return ans;
}

struct G{
    int s,w,id;
    bool operator<(const G &t)const {
        if(t.s==s) return id<t.id;
        return s>t.s;
    }// 直接在结构体里排序方法,外面就不需要写cmp了,直接sort排序即可
};
G sum[N],l[N],win[N];
void solve()
{
    int n,r,q;
    cin>>n>>r>>q;
    for(int i=1;i<=n*2;i++)
    {
        int s;
        cin>>s;
        sum[i].s=s;
    }
    for(int i=1;i<=n*2;i++)
    {
        int w;
        cin>>w;
        sum[i].w=w;
        sum[i].id=i;
    }
    sort(sum+1,sum+1+n*2);
    while (r--)
    {
        for(int i=1;i<=n;i++)
        {
            if(sum[2*i-1].w<sum[2*i].w)
            {
                sum[2*i].s++;
                l[i]=sum[2*i-1];
                win[i]=sum[2*i];
            }
            else
            {
                sum[2*i-1].s++;
                l[i]=sum[2*i];
                win[i]=sum[2*i-1];
            }
        }
        merge(l+1,l+1+n,win+1,win+1+n,sum+1);

    }
    cout<<sum[q].id;
}
signed main(){
    std::ios::sync_with_stdio(false);
    std::cin.tie(nullptr);
    int T=1;
//    cin>>T;
    while(T--){
        solve();
    }
    return 0;
}

 

posted @ 2024-03-22 00:23  whatdo+  阅读(6)  评论(0编辑  收藏  举报