2013編程之美複賽A :无尽的编号 數據結構+貪心
2013-04-20 17:44
330 查看
這次比賽太水了,怎麼可以把A題過了,然後把D題小數據過了就可以進決賽?!(很顯然,我的修行還不夠,沒能進。。。)
1) 编号要比前一个建筑(起点方向)的字典序大,比后一个建筑(终点方向)的字典序小
3) 编号一定以1结尾
2) 编号要尽可能短,满足该条件时,字典序尽可能小
最开始时,公路的起点和终点上各有一个建筑,编号分别是0和1。接下来依次给出N个坐标 a1, a2, ..., aN,依次表示下一个建筑将要建造的位置,最后要问,当所有建筑建成时,这些建筑的编号总长度是多少,其中又出现了多少个字符1。所有建筑都在公路起点和终点之间,并且没有两个建筑建在同一个位置。
第一行,给出一个整数T,为数据组数。接下来依次给出每组测试数据。
每组数据中第一行为一个整数 N,表示将要建造的建筑数量,第二行是用单个空格隔开的N个互不相同的整数 a1, a2, ..., aN,表示依次将要建造的建筑所在的坐标。
大数据:T ≤ 10, 0 < N ≤ 50000, 0 ≤ ai ≤ 500000
样例输入
样例输出
分析:
假設我們上一次插入之後當前位置的最近的左邊位置的串的長度為len1,串中1的個數為num1,最近的右邊的串長度為len2,串中1的個數為num2。我們不難發現,當前位置的1的個數最小為 num1+1,長度最小為 max(len1,len2)
對此,我們可以通過用樹狀數組或者平衡樹、線段樹、SET之類的來維護一下就行了。
一組數據:
代碼如下:
题目列表 > 无尽的编号
时间限制: 1000ms 内存限制: 256MB描述
在一条公路上,将要依次建造N座建筑。在每个建筑建成之后,都会用一个01串来给它编号。整条公路从起点到终点,所有建筑的编号都严格按照字典序递增的顺序来排列,而每在一个新的地方建起一个建筑时,它的编号会按以下规则确定:1) 编号要比前一个建筑(起点方向)的字典序大,比后一个建筑(终点方向)的字典序小
3) 编号一定以1结尾
2) 编号要尽可能短,满足该条件时,字典序尽可能小
最开始时,公路的起点和终点上各有一个建筑,编号分别是0和1。接下来依次给出N个坐标 a1, a2, ..., aN,依次表示下一个建筑将要建造的位置,最后要问,当所有建筑建成时,这些建筑的编号总长度是多少,其中又出现了多少个字符1。所有建筑都在公路起点和终点之间,并且没有两个建筑建在同一个位置。
输入
输入文件包含多组测试数据。第一行,给出一个整数T,为数据组数。接下来依次给出每组测试数据。
每组数据中第一行为一个整数 N,表示将要建造的建筑数量,第二行是用单个空格隔开的N个互不相同的整数 a1, a2, ..., aN,表示依次将要建造的建筑所在的坐标。
输出
对于每组测试数据,输出一行"Case #X: Y Z",其中X表示测试数据编号,Y表示所有建筑编号总长,Z表示所有编号中字符1的数量。所有建筑包括起点和终点的这两个建筑。所有数据按读入顺序从1开始编号。数据范围
小数据:T ≤ 100, 0 < N ≤ 100, 0 ≤ ai ≤ 1000大数据:T ≤ 10, 0 < N ≤ 50000, 0 ≤ ai ≤ 500000
样例输入
1 5 1 2 3 4 5
样例输出
Case #1: 22 16
分析:
假設我們上一次插入之後當前位置的最近的左邊位置的串的長度為len1,串中1的個數為num1,最近的右邊的串長度為len2,串中1的個數為num2。我們不難發現,當前位置的1的個數最小為 num1+1,長度最小為 max(len1,len2)
對此,我們可以通過用樹狀數組或者平衡樹、線段樹、SET之類的來維護一下就行了。
一組數據:
數據: 3 5 1 2 3 4 5 5 5 4 3 2 1 3 2 1 3 答案: Case #1: 22 16 Case #2: 22 6 Case #3: 10 5
代碼如下:
/* 分析: 假設我們上一次插入之後當前位置的最近的左邊位置的串的長度為len1, 串中1的個數為num1,最近的右邊的串長度為len2,串中1的個數為num2。 我們不難發現,當前位置的1的個數最小為 num1+1,長度最小為 max(len1,len2) 對此,我們可以通過用樹狀數組或者平衡樹、線段樹、SET之類的來維護一下 就行了。 */ #include <set> #include <map> #include <cmath> #include <queue> #include <stack> #include <string> #include <vector> #include <cstdio> #include <cstring> #include <iostream> #include <algorithm> using namespace std; typedef long long ll; typedef unsigned long long ull; #define lx(x) (x<<1) #define rx(x) (x<<1|1) #define debug puts("here") #define rep(i,n) for(int i=0;i<n;i++) #define rep1(i,n) for(int i=1;i<=n;i++) #define REP(i,a,b) for(int i=a;i<=b;i++) #define foreach(i,vec) for(unsigned i=0;i<vec.size();i++) #define pb push_back #define RD(n) scanf("%d",&n) #define RD2(x,y) scanf("%d%d",&x,&y) #define RD3(x,y,z) scanf("%d%d%d",&x,&y,&z) #define RD4(x,y,z,w) scanf("%d%d%d%d",&x,&y,&z,&w) /******** program ********************/ struct node{ int id,val,len; node(){} node(int _x,int _v,int q):id(_x),val(_v),len(q){} friend bool operator < (node a,node b){ return a.id>b.id; } void out(){ cout<<id<<" "<<val<<" "<<len<<endl; } }; set<node> s; int main(){ #ifndef ONLINE_JUDGE freopen("sum.in","r",stdin); //freopen("sum.out","w",stdout); #endif int ncase,n; RD(ncase); rep1(Ncase,ncase){ printf("Case #%d: ",Ncase); int x; RD(n); set<node>::iterator it; s.clear(); s.insert( node(-1,0,1) ); // 可以為0 s.insert( node(10000000,0,1) ); // 可以為500000,這兩處比賽過程中我WA了n次 = =。 ll ans = 0; ll r = 0; rep1(i,n){ RD(x); it = s.lower_bound( node(x,0,0) ); node pre = *it; * it --; node nex = *it; int one = pre.val+1; ans += one; int len = max(nex.len , pre.len)+1; r += len; s.insert( node(x,one,len) ); } cout<<r+2<<" "<<ans+1<<endl; } return 0; }
相关文章推荐
- Word2013对公式处理:样式、自动编号、交叉引用
- CRM 2013 生成自动编号
- word2013标题编号变成黑框
- 华为2013校招之哈工大威海 上机试题之一:报数问题:设有N 个人围坐一圈并按顺时针方向从1 到N 编号,从第S个人开始进行1 到M报数,报 数到第 M个人时,此人出圈,再从他的下一个人重新开始1 到 M的报数,如此进行下去直 到所有的人都出圈为止。现要打印出出圈次序。
- Dynamic CRM 2013学习笔记(四)单据编号及插件批量注册工具
- word2013 图片与表格自动更新编号
- Word 2013中多级标题自动编号方法
- 2013編程之美 集会 三分
- word2013多级列表自动编号与多样式配合排版
- Word 2013 多级自动编号设置
- Dynamic CRM 2013学习笔记(四)单据编号及插件批量注册工具
- 2013编程之美挑战赛---无尽的编号
- Word2013对公式处理:样式、自动编号、交叉引用
- 2013微软暑期实习笔试&面试总结
- VS2012完全卸载与VS2013安装
- 命令行编译vs2013项目
- 【索引】2013 Multi-University Training Contest
- SharePoint 2010/2013/2016内容数据库与网站集的关系
- 3107: [cqoi2013]二进制a+b
- 左右编号树型结构