• 循环序列 + 合并游戏


    1.循环序列

    (circulate.cpp/c/pas)

    (1s/256M)

    题目描述

    Alice与Bob在玩游戏:

    Alice首先给出两个数X与Y(X<=Y);

    Bob则按顺序将X,X+1,X+2,…,Y-1,Y写成一个大数S。

    Alice最后将S首尾相连,让其围成一个圈。

    这时,Bob想知道,从S的开头出发,往后的第L到第R数字之和是多少。

    输入格式(circulate.in)

    第一行四个整数X,Y,L,R,代表Alice的两个数字和Bob想要知道的第L位到第R位的数字之和。

    输出格式(circulate.out)

    仅一行,一个整数M,代表第L位到第R位的数字之和。

    样例输入

    10 11 4 12

    样例输出

    7

    样例解释

    Bob将数字写成一行大数S = 1011;围成一个圈后,从第4位到第12位分别是1,1,0,1,1,1,0,1,1,它们的和是7.

    数据范围与限制

    对于50%的数据,L=1, X,Y,L,R<=1000;

    对于100%的数据,S的长度不大于10000,X,Y,L,R<=100000000.

    ~(≧▽≦)/~啦啦啦思路:

    首先按题目要求将xy之间的数拆分存到一个数组中,然后用另一个数组将该数组倒叙存储,(便于计算),运用前缀和,取整环和不完整环,相加

    (v)~ 代码:

     1 #include<iostream>
     2 #include<cstdio>
     3 using namespace std;
     4 
     5 const int N = 1e5 + 6;
     6 int x,y,r,l,n,m;
     7 int a[N],s[N],b[N];
     8 
     9 void work(int x,int y){
    10     n=0;
    11     for(int i=x;i<=y;i++){
    12         m=0;
    13         for(int t=i; t ;t/=10) b[++m]=t%10;
    14         for(int t=m; t ;t--) a[++n]=b[t];
    15     }
    16     s[0] = 0;
    17     for(int i=1;i<=n;i++) s[i]= s[i-1] + a[i];//前缀和 
    18 }
    19 
    20 int cal(int p){
    21     if(p == 0) return 0;
    22     int g = (p-1)/n;//
    23     int r = (p-1)%n + 1;//
    24     return s[n] * g + s[r];
    25 }
    26 
    27 int main() {
    28     cin>>x>>y;
    29     cin>>l>>r;
    30     work(x,y);
    31     cout<<cal(r)-cal(l-1);
    32     return 0;
    33 } 

     

    /*----------------分割线-------------------*/

     

    2.合并游戏

    merge.cpp/c/pas

    (1s/256M)  

    题目描述

           Cindy和Dan在玩一个游戏。

           一开始Cindy想出了N个数,接着她把这N个数全部给了Dan。

           Dan得到这组数后,它会挑出3个数(如果不足3个则全部挑出)。Dan会把这几个数加起来变成一个数,然后再把这个数与剩下的数再放到一起。Dan会一直这样做,直到最后只剩下一个数。

           Cindy则会在旁边记下每次Dan得到的数,她把这些数加起来,作为本次游戏的得分。她想知道,对于一组数,Dan能得到的最大的得分是多少?

    输入格式

           第一行一个正整数N,代表这组数的个数;

           第二行N个正整数,代表这N个整数。

    输出格式

           一行一个整数,代表可能的最大得分。

    样例输入(merge.in)

           4

           3 1 5 6

    样例输出(merge.out)

           29

    样例解释

           Dan可以首先把(3,5,6)这三个数先合并起来,得到3 + 5 + 6 = 14; 接着他把剩下的两个数再合起来,得到1 + 14 = 15.这样,总得分是最大的 14 + 15 = 29.

    数据范围与限制

           对于50%的数据,N<=10

           对于100%的数据,N<=1000,所有数不大于1000

    ~(≧▽≦)/~啦啦啦思路:

    要所求值最大,就先按降序排个序,然后一次加起来就是最大,如果是在两个或以下个数中选择就特判一下。

    (v)代码:

     1 #include<cstdio>
     2 #include<iostream>
     3 #include<cstring>
     4 #include<algorithm>
     5 using namespace std;
     6 
     7 int n,a[1001],b[1001],ans,num,tot,q;
     8 
     9 int cmp(int a,int b){
    10     return a>b;
    11 }
    12 
    13 int main(){ 
    14 
    15     memset(a,-1,sizeof(a));
    16     int head=1,tail=head+2;
    17     cin>>n;
    18     
    19     for(int i=1;i<=n;i++){
    20         cin>>a[i];
    21     }sort(a+1,a+n+1,cmp);
    22     
    23     do{
    24         for(int i=head;i<=tail;i++) {
    25             num+=a[i];
    26             a[i]=-1;
    27         }a[tail]=num;
    28         ans+=a[tail];
    29         head+=tail-1;
    30         tail=head+2;
    31         for(int i=1;i<=n;i++)
    32           if(a[i]!=-1) tot++;
    33     } while(tot>=3);
    34     
    35     for(int i=1;i<=n;i++)
    36         if(a[i]!=-1) tot++;
    37         
    38     if(tot<3){
    39         for(int i=1;i<=n;i++)
    40         if(a[i]!=-1)  q=i;
    41         ans+=a[q]+a[q+1];
    42     }
    43     
    44     cout<<ans<<endl;
    45     return 0;
    46 }

    自己选的路,跪着也要走完!!!

  • 相关阅读:
    设计模式复习笔记08
    Docker Dockerfile 指令详解与实战案例
    Docker数据管理与挂载管理
    Docker简介与安装
    Xshell如何配置并远程连接Linux服务器详解
    如何VMware创建Linux虚拟机并设置虚拟机网络
    自动化运维工具Ansible之LNMP实践环境部署
    自动化运维工具Ansible之Roles角色详解
    自动化运维工具Ansible之Tests测验详解
    Ansible Jinja2 模板使用
  • 原文地址:https://www.cnblogs.com/wsdestdq/p/6815842.html
Copyright © 2020-2023  润新知