• 2021 CCPC桂林G E D【二分、区间贪心、有向最小环】


    A I 签到题

    G题二分+贪心

    代码

    1. #include
    2. using namespace std;
    3. #define int long long
    4. #define N 1000006
    5. #define inf 0x3f3f3f3f3f
    6. int T,n,m;int va[N];string s;
    7. int suml[N],sumr[N];int vis[N];
    8. bool check(int mid)
    9. {
    10. for(int i=1;i<=n;i++)vis[i]=0;
    11. for(int i=1;i<=n;i++){
    12. if(s[i]=='0'){
    13. int minn=min(i-suml[i],sumr[i]-i)+1; //最近的1到自己的距离+1,1是选择一次的时间
    14. if(minn<=mid)continue;
    15. if(minn==mid+1){ //最多能处理这些
    16. if(suml[i]>=1&&!vis[suml[i]]){ //尽量用左边的1,右边的留给别人,这样最贪心
    17. vis[suml[i]]=1;continue;
    18. //如果刚好,vis先置为1,如果已经有了,那么就算了
    19. }
    20. if(sumr[i]<=n&&!vis[sumr[i]]){
    21. vis[sumr[i]]=1;continue;
    22. }
    23. }
    24. return false;
    25. }
    26. }
    27. return true;
    28. }
    29. signed main()
    30. {
    31. ios::sync_with_stdio(0);
    32. cin>>T;
    33. while(T--){
    34. cin>>n;cin>>s;s="!"+s;
    35. int maxnl=-inf,maxnr=inf;
    36. for(int i=1;i<=n;i++){
    37. if(s[i]=='0')suml[i]=maxnl; //maxnl是左边而来的1
    38. else maxnl=i;
    39. }
    40. for(int i=n;i>=1;i--){
    41. if(s[i]=='0')sumr[i]=maxnr; //maxnr是右边而来的1
    42. else maxnr=i;
    43. }
    44. int l=0,r=n;
    45. while(l
    46. int mid=(l+r)>>1;
    47. if(check(mid))r=mid;
    48. else l=mid+1;
    49. }
    50. cout<"\n";
    51. }
    52. return 0;
    53. }

    E. Buy and Delete(有向最小环)

    Problem - E - Codeforces

    题意:

    G图有n个点,首先G图无边,Alice买了一些边放到G里。之后,Bob删边,Bob删子集SS,SS里面无环。商店里有m条边,Alice有c元。Alice要使Bob删掉的次数最大化,求Bob删的回数

    思路:

    买不起--0,无环--1,有环--2

    如果一条边都买不起的话,输出0;不然直接先置为1;假设把商店里所有边都放到G图里,在G中求有向图最小环;

    有向最小环的寻找方式:有向图求最小环【里面还有 有向最大环 有向判负环】

    这里采用Dijkstra算法

    代码:

    1. #include
    2. using namespace std;
    3. #define int long long
    4. #define INF 0x3f3f3f3f
    5. typedef pair<long long,int> pll;
    6. vectormp[2005];int dis[2005][2005];bool vis[2005];
    7. int ans=0;bool flag=0;int n,m,c;
    8. void dijkstra(int u)
    9. {
    10. for(int i=1;i<=n;i++) dis[u][i]=INF;
    11. memset(vis,0,sizeof vis);
    12. dis[u][u]=0;
    13. priority_queue,greater >heap;
    14. heap.push({0,u});
    15. while (heap.size()){
    16. pll t=heap.top();heap.pop();
    17. int ver=t.second;
    18. if (vis[ver]) continue;
    19. vis[ver]=true;
    20. for(auto k:mp[ver]){
    21. if(!vis[k.second]&&dis[u][k.second]>dis[u][ver]+k.first){
    22. dis[u][k.second]=dis[u][ver]+k.first;
    23. heap.push({dis[u][k.second],k.second});
    24. }
    25. }
    26. }
    27. }
    28. signed main()
    29. {
    30. cin>>n>>m>>c;
    31. for(int i=1;i<=m;i++){
    32. int uu,vv,p;cin>>uu>>vv>>p;
    33. mp[uu].push_back({p,vv});
    34. if(c>=p){ans=1;}
    35. }
    36. if(ans==0){cout<<0;return 0;}
    37. int minn=INF;
    38. for(int i=1;i<=n;i++)dijkstra(i);
    39. for(int i=1;i<=n;i++){
    40. for(int j=0;jsize();j++){
    41. minn=min(minn,mp[i][j].first+dis[mp[i][j].second][i]);
    42. }
    43. }
    44. if(minn<=c)ans=2;
    45. cout<
    46. return 0;
    47. }

    D. Assumption is All You Need(贪心 暴力)

    题意:

     对于A数组中每个逆序对,交换它们,输出交换策略

    思路:

    贪心+暴力。

    参考:2021 CCPC 桂林站 ADEGIK 

    如果该位上a[i]和b[i]上的一样,就没有换的必要了;

    如果该位上a[i]要比b[i]的小,a[i]前面的已经有序,没有换的必要;由于只能逆序对交换元素,a[i]的后面再怎么换也只能换比a[i]更小的,无解,输出-1。

    如果该位上a[i]要比b[i]的大,遍历a[i]后面的每一位元素a[j],如果存在小于a[i](符合交换条件)、大于等于b[i](逼近b[i]),则进行交换;

    在进行每一次交换后,a[i]的值势必会渐渐接近b[i]最后等于b[i],而不断地交换也可以使得当前较大的元素最大限度地留在较前的位置(较早地被swap了而不是找到匹配元素再进行交换)。

    注意:

    记得取消同步 不然会超时 ios::sync_with_stdio(0);cin.tie(0);

    代码:

    1. #include
    2. using namespace std;
    3. int a[2030],b[2030];
    4. int pos[2030];int n;
    5. vectorint,int> >ans;
    6. void solve(){
    7. ans.clear();
    8. int n;cin>>n;
    9. for(int i=1;i<=n;i++)cin>>a[i];
    10. for(int i=1;i<=n;i++)cin>>b[i];
    11. for(int i=1;i<=n;i++){
    12. if(a[i]==b[i])continue;
    13. else if(a[i]-1<<'\n';return;}
    14. else if(a[i]>b[i]){
    15. for(int j=i+1;j<=n;j++){
    16. if(a[j]=b[i]){//满足逆序且逐渐逼近b[i]
    17. swap(a[j],a[i]);
    18. ans.push_back({i,j});
    19. if(a[i]==b[i])break;
    20. }
    21. }
    22. }
    23. }
    24. cout<size()<<'\n';
    25. for(int i=0;isize();i++){
    26. cout<" "<'\n';
    27. }
    28. }
    29. int main()
    30. {
    31. ios::sync_with_stdio(0);cin.tie(0);
    32. int T;cin>>T;
    33. while(T--){
    34. solve();
    35. }
    36. return 0;
    37. }

  • 相关阅读:
    大数据面试重点之mysql篇
    Python中计算程序的运行时间——timeit模块
    SmartInspect Professional .Net & Delphi Crack
    面渣逆袭:Redis连环五十二问,三万字+八十图详解。
    Vue.js 进阶技巧:keep-alive 缓存组件解析
    面试官:Spring中都应用了哪些设计模式?
    1731. 每位经理的下属员工数量
    【C#】RestSharp踩坑日记
    如何快速实现多人协同编辑?
    基于JAVA中学网站设计与实现演示录像2020计算机毕业设计源码+系统+数据库+lw文档+部署
  • 原文地址:https://blog.csdn.net/zy98zy998/article/details/127758418