P8762 [蓝桥杯 2021 国 ABC] 123
题意:一个规律的序列,求l到r的和。
思路: 1 1 2 1 2 3 1 2 3 4 ,先求有几个1到n的和,然后根据a[i]=n(n+1)/2求出s=n(n+1)(n+2)/6求出这些和,后加上1到k
代码:
#include<bits/stdc++.h>
using namespace std;
#define ll long long
ll t,l,r;
ll sum(ll x){
ll n=(-1+ sqrt(1+8.0*x))/2;
ll s;
ll k;
k=x-n*(n+1)/2;
s=n*(n+1)*(n+2)/6+(k+1)*k/2;
return s;
}
int main(){
cin>>t;
while (t--){
cin>>l>>r;
ll sl,sr;
sl=sum(l-1),
sr=sum(r);
cout<<sr-sl<<endl;
}
}
P8686 [蓝桥杯 2019 省 A] 修改数组
题意:给一个数组,对每一个位置的元素,如果在前面没出现过,输出,如果出现过,就输出最小的没出现过的元素
思路:如果用set求解的话,由于n++,则会超时,因此考虑并查集,数据范围是1e6,不会超时;
- 每一个数字的父节点是他自己,先把a【i】=find(a[i]),然后父节点就会加1,这样可以保证下一次这个数出现时,直接求他的父节点就可以了,这个父节点在前面不可能出现过,且最小
代码:
#include<bits/stdc++.h> using namespace std; int f[1000006]; int n,a[100005]; int find(int x){ if(x!=f[x]){ f[x]=find(f[x]); } return f[x]; } int main(){ cin>>n; for (int i = 1; i <=1000000 ; ++i) { f[i]=i; } for (int i = 1; i <=n ; ++i) { cin>>a[i]; a[i]=find(a[i]); f[a[i]]=find(a[i])+1; } for (int i = 1; i <=n ; ++i) { cout<<a[i]<<' '; } }
P8685 [蓝桥杯 2019 省 A] 外卖店优先级
题意:
n个外卖点,有一个星值:x,每过一秒,如果没有订单,则-1,直到0,如果有订单,则+2,如果大于等于5,则变为推荐位,如果是推荐位,但x值<=3,则会被取消推荐,问第k秒时,有几个外卖点是推荐位。
思路:运用优先队列q[k]来维护每一秒的订单情况,然后把每一秒的订单情况从队列中全部取出,因为每一秒都会--,那我们可以用一个变量sj来记录减了多少,然后当有订单的时候,不用--,那我们可以+3,然后判断当前的星值-sj>=5,则入map,map记录的是推荐位的,然后遍历map,如果他的second<=3,则删除,每一秒重复,直到K秒时,输出map.size();
代码:
#include<bits/stdc++.h> using namespace std; priority_queue<int,vector<int>,greater<int> >q[100005]; int store[100001]; int n,m,t; int main(){ cin>>n>>m>>t; for (int i = 0; i <m; ++i) { int ts,td; cin>>ts>>td; q[ts].push(td); } int sj=0; map<int ,int >a; for (int i = 1; i <=t ; ++i) { sj++; int fro,c; while (!q[i].empty()){ fro=q[i].top();c=0; while (!q[i].empty()&&fro==q[i].top()){ c++; q[i].pop(); } if(store[fro]<sj){ store[fro]=sj+2*c; } else{ store[fro]=store[fro]+2*c+1; } if(store[fro]-sj>5){ a[fro]=store[fro]; } } for(map<int,int>::iterator it=a.begin();it!=a.end();) { if(it->second-sj<=3) a.erase(it++); else it++; } // for (auto t:a) { // auto g=t; // if(t.second-sj<=3){ // a.erase(g.first); // } // } } cout<<a.size()<<endl;
}