- /*
- Title: Gold Balanced Lineup
- Author: Jeff
- Time: 2008/11/19
- Complexity: O(nlogn);
- Result: different below/ AC
- Reference:
- http://www.cppblog.com/sicheng/archive/2008/09/07/28532.html
- http://www.cppblog.com/Hero/archive/2008/08/30/60441.html
- Description:
- 给出100000个数,求出balance最长范围。
- balance的定义是:[i,j]范围内的数的各个位加起来相等。
- 如 4 2 1各个位加起来分别是 1 1 1相等
- 而 4 2 2各个位加起来分别是 1 2 0不相等
- Tips:
- 一开始无从下手(题目分类是hash, 排序),还是上网搜了下,结果要
- 先预处理下,将每个数分解为K位0/1表示的数。
- 如:
- 7 3
- 7 6 7 2 1 4 2
- 分解:
- 1 1 1 0 0 1 0
- 1 1 1 1 0 0 1
- 1 0 1 0 1 0 0
- 累加:横方向
- 1 2 3 3 3 4 4
- 1 2 3 4 4 4 5
- 1 1 2 2 3 3 3
- 相减:纵方向
- 0 1 1 1 0 1 1
- 0 1 1 2 1 1 2
- 0 0 0 0 0 0 0
- - -
- 再找两边相等bits的且间隔最长的距离就是结果(因为两边相等说明经过中间
- 的步骤是满足balance条件的)
- p.s.
- 注意只有1个balance距离的情况,因为上面可能找不到两个相等的bits,所以
- 在开头增加一个(0 0 0)'
- 同样为节省时间,输入用了getchar(),再化为int
- */
- #include <cstring>
- #include <cstdio>
- #include <algorithm>
- #include <map>
- #include <vector>
- using namespace std;
- const int MAX = 100002;
- int N, K;
- struct Node{
- int bits[32];
- int idx;
- bool operator<(const Node &other)const{
- for(int i = 0; i < K; i++)
- if(bits[i] < other.bits[i])return true;
- else if(bits[i] == other.bits[i])continue;
- else return false;
- return false;
- }
- bool operator==(const Node &other)const{
- for(int i = 0; i < K; i++)
- if(bits[i] != other.bits[i])return false;
- return true;
- }
- }node[MAX];
- int min(int a, int b){
- return a < b ? a : b;
- }
- int max(int a, int b){
- return a > b ? a : b;
- }
- int main(){
- freopen("in.txt", "r", stdin);
- freopen("out.txt", "w", stdout);
- while(scanf("%d%d", &N, &K) != EOF){
- char ch = getchar();
- for(int i = 1; i <= N; i++){
- while(ch == ' ' || ch == '/n')ch = getchar();
- int x = 0;
- while(ch != ' ' && ch != '/n'){
- x = x * 10 + ch - '0';
- ch = getchar();
- }
- for(int j = 0; j < K; j++){
- node[i].bits[j] = 1 & (x >> j);
- }
- node[i].idx = i;
- }
- memset(&node[0], 0, sizeof(node[0]));
- for(int i = 1; i <= N; i++)
- for(int j = 0; j < K; j++)
- node[i].bits[j] += node[i-1].bits[j];
- for(int i = N; i >= 0; i--)
- for(int j = K-1; j >= 0; j--)
- node[i].bits[j] -= node[i].bits[0];
- /*for(int i = 0; i < N; i++){
- for(int j = 0; j < K; j++)
- printf("%d ", node[i].bits[j]);
- printf("/n");
- }
- printf("/n"); */
- //
- // 13248K 407MS 快排
- //
- sort(node, node + N + 1);
- int min_n = 1 << 28, max_n = 0, ans = 0;
- for(int i = 1; i <= N; i++){
- if(node[i] == node[i-1]){
- int min_t = min(node[i].idx, node[i-1].idx);
- int max_t = max(node[i].idx, node[i-1].idx);
- if(min_n > min_t)min_n = min_t;
- if(max_n < max_t)max_n = max_t;
- if(ans < max_n - min_n)ans = max_n - min_n;
- }else{
- min_n = 1 << 28;
- max_n = 0;
- }
- }
- printf("%d/n", ans);
- /
- /
- /*
- /
- // 29828K 1797MS map
- /
- map<Node, int> mym;
- vector<int> l[MAX];
- int j = 0;
- for(int i = 0; i <= N; ++i) {
- if(mym.find(node[i]) == mym.end())
- mym[node[i]] = j++;
- l[mym[node[i]]].push_back(i);
- }
- int res = 0;
- for(int i = 0; i < j; ++i) {
- int min = 123456789, max = -1;
- for(int k = 0; k < l[i].size(); ++k) {
- if(l[i][k] > max) max = l[i][k];
- if(l[i][k] < min) min = l[i][k];
- }
- if(max - min > res) res = max - min;
- }
- printf("%d/n", res);
- //
- //
- */
- }
- return 0;
- }
PKU 3274 Gold Balanced Lineup解题报告
最新推荐文章于 2014-08-18 10:39:11 发布