开学第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; }