超级赛亚ACMer

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 1536    Accepted Submission(s): 437

Problem Description
百小度是一个ACMer,也是一个超级赛亚人,每个ACMer都有一个战斗力,包括百小度。
所谓超级赛亚人的定义,是说如果在对抗中刚好接近极限状态,那就会激发斗志,实力提升.

具体来说,就是百小度现在要接受一些ACMer的挑战了,这些ACMer有n个人,第i个人的战斗力是a[i]。


百小度接下来可以自主安排与这n个ACMer的PK顺序,他要想在PK赛中赢过另外一个ACMer,就必须使得自己的战斗力不小于对方(平局情况他会按照百小度字典上的规则把自己排在第一).

如果百小度的战斗力大于对方,那么百小度就会轻易获胜,得不到锻炼并且骄傲起来,他以后的战斗力将保持在这个值,再也不会发生改变。
如果百小度的战斗力等于对方,那么百小度在获胜的同时也会感到很吃力,但是这会激发百小度的斗志,使得他刻苦刷题,在下场PK赛之前,战斗力最多提升k点(即可以提升0~k点任意值).

k是百小度的潜力提升上限,会被给定一个初始值,这个潜力提升上限k在后面的比赛中会下降.

每战胜一个ACMer,这个潜力上限k将减少1(因为超级赛亚人百小度也会感到累),但k最低只会减少到0,即不会出现战斗力下降的情况
。也就是第一次比赛如果激发了百小度的斗志,他能把战斗力提升0~k的任一值,如果第二次比赛继续被激发斗志,他能在第一次提升后的基础上,把战斗力再提升0 max(0,k−1) ,依次类推…

m是百小度的初始战斗力上限,也就是百小度第一次进行PK赛的时候,可以选择0~m的任意一个值作为他的战斗力.

现在希望你编写程序,判断一下百小度是否战胜所有的ACMer.

Input
输入包含多组数据(数据不超过500组)

第一行一个整数T,表示T组数据

对于每组数据,第一行包括三个整数n,m,k(1≤n≤104,1≤m,k≤108)

第二行包括n个正整数,表示彪形大汉的战斗力(战斗力为不超过1012 的正整数)

Output
对于每组数据,先输出一行Case #i: (1≤i≤T)

如果百小度能打败所有的ACMer,再输出"why am I so diao?"

否则再输出"madan!"

Sample Input
2
5 11 3
15 13 10 9 8
5 11 3
8 9 10 13 16

Sample Output
Case #1:
why am I so diao?
Case #2:
madan!

Hint

第一组样例解释 5个ACMer,初始战斗力选择范围是[0,11],接下来每场战斗力提升上限是3,2,1,0,0,...,0 百小度首先使得自己的初始战斗力为10,打败战斗力为10的第一个ACMer, 然后选择战斗力提升3,变成13,打败战斗力为13的第二个ACMer, 然后选择战斗力提升2,变成15,打败战斗力为15的第三个ACMer, 之后再以任意顺序打败剩下的ACMer

Source
2015年百度之星程序设计大赛 - 初赛(1) 
题意:   就好比上台阶,每次自己跳跃的高度有限,怎么样跳到顶点是一个思路。
思路:    对于给定的那些战斗力的进行升序排序,然后采取贪心策略,每次尽可能的往上走。
代码:
 1 #include <stdio.h>
 2 #include<algorithm>
 3 #define maxn 10005
 4 long long aa[maxn];
 5 int main()
 6 {
 7     int cnt=1,cas,i;
 8     long long nn,mm,kk,res;
 9     scanf("%d",&cas);
10     while(cas--){
11       scanf("%lld %lld %lld ",&nn,&mm,&kk);
12       for(i=0 ; i<nn ; i++)
13           scanf("%lld",aa+i);
14       std::sort(aa,aa+nn);
15       printf("Case #%d:\n",cnt++);
16       for(res=mm,i=0 ; i<nn ; i++ )
17           if(aa[i]<=mm) res=aa[i];
18         else break;
19
20       while(i!=0&&i<nn){
21        int j=i;
22         while(j<nn&&res+kk>=aa[j]) j++;
23         if(j==i)break;
24          else res=aa[j-1];
25         if(kk>0) kk--;
26         i=j;
27       }
28       if(res>=aa[nn-1])
29             puts("why am I so diao?");
30         else
31             puts("madan!");
32     }
33     return 0;
34 }

找连续数

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 801    Accepted Submission(s): 294

Problem Description
小度熊拿到了一个无序的数组,对于这个数组,小度熊想知道是否能找到一个k 的区间,里面的 k 个数字排完序后是连续的。

现在小度熊增加题目难度,他不想知道是否有这样的 k 的区间,而是想知道有几个这样的 k 的区间。

Input
输入包含一组测试数据。

第一行包含两个整数n,m,n代表数组中有多少个数字,m 代表针对于此数组的询问次数,n不会超过10的4次方,m 不会超过1000。第二行包含n个正整数,第 I 个数字代表无序数组的第 I 位上的数字,数字大小不会超过2的31次方。接下来 m 行,每行一个正整数 k,含义详见题目描述,k 的大小不会超过1000。

Output
第一行输"Case #i:"。(由于只有一组样例,只输出”Case #1:”即可)

然后对于每个询问的 k,输出一行包含一个整数,代表数组中满足条件的 k 的大小的区间的数量。

Sample Input
6 2 3 2 1 4 3 5 3 4
Sample Output
Case #1: 2 2
Source
2015年百度之星程序设计大赛 - 初赛(1) 
思路:  对于一个集合{a1,a2,a3,a4, .... an }map,我们如何知道里面的数是连续,其实只需要满足这样的特征: 集合中最大值 和集合中最小值的差+1 = 集合中元素的个数 。  我们就可以去说,这个集合是连续的。
 1 #include<iostream>
 2 #include<map>
 3 #include<stdio.h>
 4 #include<string.h>
 5
 6 const int maxn= 10005;
 7 int n,m,k;
 8 int aa[maxn];
 9 int res[1005];
10 int main()
11 {
12    int T,cas=1;
13    int max_a ,min_a ;
14    std::map<int ,bool>tmp ;
15   while(~scanf("%d%d",&n,&m)){
16
17    for(int i=0;i<n;i++)
18          scanf("%d",aa+i);
19     //采用离线的方法
20     memset(res, 0,sizeof(res));
21     for(int i=0;i<n ;i++){
22             max_a = aa[i];
23             min_a = aa[i];
24             tmp.clear();
25        for(int j=i ; j<n&&j<1000+i;j++){
26             if(max_a < aa[j] ) max_a = aa[j];
27             if(min_a > aa[j] ) min_a = aa[j];
28              tmp[aa[j]]=true;
29           if(max_a -min_a==j-i&&max_a -min_a+1==tmp.size())
30             res[max_a -min_a+1]++;
31        }
32     }
33     printf("Case #%d:\n",cas++);
34    for(int i=0; i<m;i++)
35    {
36         scanf("%d",&k);
37         printf("%d\n",res[k]);
38    }
39    }
40  return 0;
41 }

很危险的滑了过去...920ms

序列变换

Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 581    Accepted Submission(s): 287

Problem Description
给定序列A={A1,A2,...,An} , 要求改变序列A中的某些元素,形成一个严格单调的序列B(严格单调的定义为:Bi<Bi+1,1≤i<N )。

我们定义从序列A到序列B变换的代价为cost(A,B)=max(|Ai−Bi|)(1≤i≤N) 。

请求出满足条件的最小代价。

注意,每个元素在变换前后都是整数。

Input
第一行为测试的组数T(1≤T≤10) .

对于每一组:
第一行为序列A的长度N(1≤N≤105) ,第二行包含N个数,A1,A2,...,An .
序列A中的每个元素的值是正整数且不超过106 。

Output
对于每一个测试样例,输出两行:

第一行输出:"Case #i:"。i代表第 i 组测试数据。

第二行输出一个正整数,代表满足条件的最小代价。

Sample Input
2 2 1 10 3 2 5 4
Sample Output
Case #1: 0 Case #2: 1
Source
2015年百度之星程序设计大赛 - 初赛(1) 

题意:  其实求的最小代价res,就是对于任意集合A{},使得里面的元素+—res,成为一个单调数列....
刚开始搞不懂题目究竟是什么意思! ╮(╯▽╰)╭
简单的二分
代码:

 1 #include<stdio.h>
 2 #include<stdlib.h>
 3 #include<math.h>
 4 #define maxn  100005
 5 int aa[maxn];
 6
 7 bool solve(int var ,int n){
 8      //对于a[i]+|- var 变成单调数列
 9    int tmp = var +aa[n-1];
10     for(int i=n-2; i>=0 ;i-- ){
11          if (abs(tmp - 1 - aa[i]) <= var)
12                tmp = tmp - 1;
13         else if (tmp - 1 >= aa[i])
14             tmp = aa[i] + var;
15         else
16             return 0;
17     }
18   return 1;
19 }
20 int main()
21 {
22  int t,n;
23  scanf("%d",&t);
24  for(int cas=1;cas<=t;cas++){
25      scanf("%d",&n);
26     for(int i=0; i<n ;i++)
27         scanf("%d",aa+i);
28
29     printf("Case #%d:\n",cas);
30     int mid ,ri=1000005,le=0;
31     while(le<ri){
32          mid = le +((ri-le)>>1L);
33         //判断是否为单调数列
34         if(solve(mid,n))
35             ri=mid ;
36         else
37             le = mid+1;
38     }
39     printf("%d\n",le);
40  }
41  return 0;
42 }

KPI

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 639    Accepted Submission(s): 267

Problem Description
你工作以后, KPI 就是你的全部了. 我开发了一个服务,取得了很大的知名度。数十亿的请求被推到一个大管道后同时服务从管头拉取请求。让我们来定义每个请求都有一个重要值。我的KPI是由当前管道内请求的重要值的中间值来计算。现在给你服务记录,有时我想知道当前管道内请求的重要值得中间值。
Input
有大约100组数据。

每组数据第一行有一个n(1≤n≤10000) ,代表服务记录数。

接下来有n行,每一行有3种形式
  "in x": 代表重要值为x(0≤x≤109) 的请求被推进管道。
  "out": 代表服务拉取了管道头部的请求。
  "query: 代表我想知道当前管道内请求重要值的中间值. 那就是说,如果当前管道内有m条请求, 我想知道,升序排序后第floor(m/2)+1th 条请求的重要值.

为了让题目简单,所有的x都不同,并且如果管道内没有值,就不会有"out"和"query"操作。

Output
对于每组数据,先输出一行

Case #i:
然后每一次"query",输出当前管道内重要值的中间值。

Sample Input
6 in 874 query out in 24622 in 12194 query
Sample Output
Case #1: 874 24622
Source
2015年百度之星程序设计大赛 - 初赛(1) 
这道题刚开始用堆来处理,发现总是出错! 后来在看了下别人的解题报告,发现了一种新的思路,运用两个set集合,利用红黑树的特性。分段来进行排序
但是要总是保持这两颗树的元素个数之差保持在小于2的状态。而且要满足上层集合的个数始终大于或者等于下层集合个数。
 1 #include<stdio.h>
 2 #include<string.h>
 3 #include<set>
 4 #include<queue>
 5 #include<stdlib.h>
 6 #include<iostream>
 7
 8 int tt ,x,tmp,cnt=1;
 9 char cmd[8];
10 int main( void )
11 {
12    std::set<int> low,hig;
13
14 while(scanf("%d",&tt)!=EOF){
15         std::queue<int>aa;
16         printf("Case #%d:\n",cnt++);
17         low.clear();
18         hig.clear();
19
20   while(tt--){
21     scanf("%s",cmd);
22     if(cmd[0]=='i'){
23
24         scanf("%d",&x);
25         aa.push(x);
26      if(hig.empty()|| x > *hig.begin())
27                hig.insert(x);
28       else
29            low.insert(x);
30
31     }
32     else if(cmd[0]=='o'){
33
34          tmp=aa.front();
35          aa.pop();
36        if(low.count(tmp))
37            low.erase(tmp);
38        else
39            hig.erase(tmp);
40
41     }else if(cmd[0]=='q')
42         printf("%d\n",*hig.begin());
43
44      if(low.size()+1<hig.size()){
45             low.insert(*hig.begin());
46             hig.erase(*hig.begin());
47         }
48         else if(low.size()>hig.size()){
49             hig.insert(*low.rbegin());
50             low.erase(*low.rbegin());
51         }
52     }
53   }
54  return 0;
55 }

方法二  利用线段树处理,类似于一个单点更新和离散化处理...

  1 #include<stdio.h>
  2 #include<stdlib.h>
  3 #include<string.h>
  4 #include<queue>
  5 #include<iostream>
  6 #include<algorithm>
  7
  8
  9 using namespace std;
 10 const int maxn=10005;
 11
 12 int Hash[maxn],sum[maxn<<2];
 13 int cnt;
 14
 15 typedef struct node{
 16
 17      int var ;
 18      char cmd[6];
 19
 20 }Node;
 21
 22 void Push(int pos ){
 23     sum[pos]=sum[pos<<1]+sum[pos<<1|1];
 24 }
 25
 26  void Build(int st ,int en ,int pos){
 27     if(st==en){
 28         sum[st]=0;
 29         return ;
 30     }
 31     int mid=st+((en-st)>>1L);
 32     Build(st,mid,pos<<1);
 33     Build(mid+1,en,pos<<1|1);
 34     Push(pos);
 35  }
 36
 37  void Update(int st ,int en ,int value ,int pos ,int find_p){
 38
 39     if(st==en) {  //单点更新,说明增加或者减少一个点
 40       sum[pos]=value;
 41       return ;
 42     }
 43     int mid =st+((en-st)>>1L);
 44     if(find_p<=mid)
 45         Update(st , mid , value , pos<<1 , find_p);
 46     else
 47         Update(mid+1 , en , value , pos<<1|1 ,find_p);
 48     Push(pos);
 49  }
 50
 51  int query(int st ,int en ,int pos ,int num){
 52     if(st==en)
 53        return st;
 54     int mid = st + ((en -st)>>1L);
 55     if(sum[pos<<1]>=num)
 56       return   query(st,mid,pos<<1 , num);
 57     else
 58       return   query(mid+1,en,pos<<1|1,num-sum[pos<<1]);  //相对起点为0
 59  }
 60
 61 //学习了某位大牛的STL用法
 62 int HASH(int x ){
 63
 64     return lower_bound(Hash ,Hash+cnt,x)-Hash;
 65 }
 66
 67 Node tem[maxn];
 68 int main()
 69 {
 70     int nn,cas=1,pos;
 71     while(~scanf("%d",&nn)){
 72         queue<int>aa;
 73          cnt=0;
 74         memset(sum,0,sizeof(sum));
 75         printf("Case #%d:\n",cas++);
 76
 77         for(int i=0;i<nn;i++){
 78            scanf("%s",tem[i].cmd);
 79            if(tem[i].cmd[0]=='i'){
 80               scanf("%d",&tem[i].var);
 81               Hash[cnt++]=tem[i].var;
 82            }
 83         }
 84         sort(Hash,Hash+cnt);
 85
 86        for(int i=0;i<nn;i++){
 87              if(tem[i].cmd[0]=='i')
 88         {
 89               pos = HASH(tem[i].var);
 90               Update(1,cnt+1,1,1,pos+1);
 91            aa.push(pos);
 92
 93         }
 94         else if(tem[i].cmd[0]=='o')
 95         {
 96             pos =aa.front();
 97             aa.pop();
 98             Update(1,cnt+1,0,1,pos+1);
 99
100         }
101         else{
102
103              pos = sum[1]/2 +1;
104              pos=query(1,cnt+1,1,pos);
105              printf("%d\n",Hash[pos-1]);
106
107         }
108        }
109     }
110   return 0;
111 }

速度499ms飘然而过!

百度之星初赛(1)解题报告相关推荐

  1. 2016百度之星 - 初赛(Astar Round2B)解题报告

    此文章可以使用目录功能哟↑(点击上方[+]) 被自己蠢哭,去年还能进一下复赛,今年复赛都没戏了... 链接→2016"百度之星" - 初赛(Astar Round2B)  Prob ...

  2. 2016百度之星 - 初赛(Astar Round2A)解题报告

    此文章可以使用目录功能哟↑(点击上方[+]) 有点智商捉急,第一题卡了好久,看来不服老,不服笨是不行的了...以下是本人目前的题解,有什么疑问欢迎提出 链接→2016"百度之星" ...

  3. 二分搜索 2015百度之星初赛1 HDOJ 5248 序列变换

    题目传送门 1 /* 2 二分搜索:在0-1e6的范围找到最小的max (ai - bi),也就是使得p + 1 <= a[i] + c or a[i] - c 3 比赛时以为是贪心,榨干智商也 ...

  4. 2015百度之星初赛(1)1006 旋转卡壳

    矩形面积 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submi ...

  5. 2021百度之星初赛二(1001 -- 1003)

    2021百度之星初赛二(1001 – 1003) 1001 题意: 给 a,b,每次 a,b会变为 a+b,a-b,问 k 次之后变成了哪两个数,对 998244353998244353 取模,多组数 ...

  6. 2021百度之星初赛第一场部分题解

    写在前面 几个家长要求我写一些2021百度之星初赛第一场的题解. 1003 鸽子 原题链接 https://acm.hdu.edu.cn/showproblem.php?pid=6998 http:/ ...

  7. 2014百度之星初赛第一轮解题报告:information

    Information 时间限制: 1s 内存限制: 65536K 问题描述 军情紧急,我们需要立刻开发出一个程序去处理前线侦察兵发回的情报,并做出相应的分析.现在由你负责其中的一个子模块,你需要根据 ...

  8. 2011百度之星初赛B圆环

    这是百度之星2011初赛B中的第一道题,题目也很水,只要找到解题思路就OK了.. 题目: 时间限制:1000ms 描述 一个圆环上有n个位置,这n个位置按顺时针依次标号为1, 2, -, n.初始时圆 ...

  9. 2015Astar百度之星初赛 1005 序列变化

    序列变换 Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submi ...

最新文章

  1. 打造精简版Linux-mini
  2. 依赖Zookeeper生成全局唯一序列号
  3. 存储器间接寻址方式_8086中的数据存储器寻址模式
  4. C#LeetCode刷题之#21-合并两个有序链表(Merge Two Sorted Lists)
  5. kafka逻辑示意图以及命令
  6. TurboMail邮件系统为防垃圾邮件盗号提供专业方案
  7. 从头搭建drbd+openfiler+corosync (二)
  8. PHP-MYSQL中文乱码问题.
  9. PHP exit()与die()的区别
  10. 天涯明月刀开发_天涯明月刀手游公测上线,斗鱼暗地操作,打造第二个PDD
  11. C++黑客编程——初识(1)
  12. 《上古卷轴5重制版》支线任务
  13. 如何把Excel转成html table表格代码
  14. Zotero + 坚果云 文献管理器配置
  15. Java爬携程_Java数据爬取——爬取携程酒店数据(一)
  16. 【Love2d从青铜到王者】第一篇:Love2d入门以及安装教程
  17. QTP和翻译软件的故事
  18. 读书印记 - 《我们人类的基因:全人类的历史和未来》
  19. fpc:lazarus 安装电子表格程式 FPSpreadsheet
  20. 基于Conv3D实现三维立体MNIST数据集分类

热门文章

  1. noip2010关押罪犯
  2. 2018.3.26 1501 二叉树最大宽度和高度
  3. 蓝桥杯java 算法训练 区间K大数查询
  4. dev gridcontrol设置过滤器下拉列表
  5. 一个整数,它加上100后是一个完全平方数,再加上168又是一个完全平方数,请问该数是多少...
  6. 【转】Spring 的下载、安装和使用
  7. 从UWP到SWIFT-开始
  8. RSA加密算法原理及RES签名算法简介(转载)
  9. javaScript 验证码代码
  10. 视频场景下,新用户的推荐策略怎么做?