循环序列 + 合并游戏

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 }

 

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

posted @ 2017-05-06 10:00  橘生淮南终洛枳  阅读(181)  评论(0编辑  收藏  举报