PKU 3274 Gold Balanced Lineup解题报告

 
  1. /*
  2.   Title: Gold Balanced Lineup
  3.   Author: Jeff
  4.   Time:  2008/11/19
  5.   Complexity: O(nlogn);
  6.   Result: different below/ AC
  7.   Reference: 
  8.         http://www.cppblog.com/sicheng/archive/2008/09/07/28532.html
  9.         http://www.cppblog.com/Hero/archive/2008/08/30/60441.html
  10.   Description: 
  11.         给出100000个数,求出balance最长范围。
  12.         balance的定义是:[i,j]范围内的数的各个位加起来相等。
  13.         如 4 2 1各个位加起来分别是 1 1 1相等 
  14.         而 4 2 2各个位加起来分别是 1 2 0不相等 
  15.   Tips:
  16.         一开始无从下手(题目分类是hash, 排序),还是上网搜了下,结果要
  17.         先预处理下,将每个数分解为K位0/1表示的数。 
  18.         如:
  19.         7 3 
  20.         7 6 7 2 1 4 2 
  21.         分解:
  22.         1 1 1 0 0 1 0
  23.         1 1 1 1 0 0 1
  24.         1 0 1 0 1 0 0
  25.         累加:横方向 
  26.         1 2 3 3 3 4 4
  27.         1 2 3 4 4 4 5
  28.         1 1 2 2 3 3 3
  29.         相减:纵方向
  30.         0 1 1 1 0 1 1
  31.         0 1 1 2 1 1 2
  32.         0 0 0 0 0 0 0
  33.           -       -
  34.         再找两边相等bits的且间隔最长的距离就是结果(因为两边相等说明经过中间
  35.         的步骤是满足balance条件的)
  36.   p.s. 
  37.         注意只有1个balance距离的情况,因为上面可能找不到两个相等的bits,所以
  38.         在开头增加一个(0 0 0)' 
  39.         同样为节省时间,输入用了getchar(),再化为int 
  40. */
  41. #include <cstring>
  42. #include <cstdio>
  43. #include <algorithm>
  44. #include <map>
  45. #include <vector>
  46. using namespace std;
  47. const int MAX = 100002;
  48. int N, K;
  49. struct Node{
  50.     int bits[32];
  51.     int idx;    
  52.     bool operator<(const Node &other)const{
  53.         for(int i = 0; i < K; i++)
  54.             if(bits[i] < other.bits[i])return true;
  55.             else if(bits[i] == other.bits[i])continue;
  56.             else return false;
  57.         return false;
  58.     }
  59.     bool operator==(const Node &other)const{
  60.         for(int i = 0; i < K; i++)
  61.             if(bits[i] != other.bits[i])return false;
  62.         return true;
  63.     }
  64. }node[MAX];
  65. int min(int a, int b){
  66.     return a < b ? a : b;    
  67. }
  68. int max(int a, int b){
  69.     return a > b ? a : b;    
  70. }
  71. int main(){
  72.     freopen("in.txt""r", stdin);
  73.     freopen("out.txt""w", stdout);
  74.     while(scanf("%d%d", &N, &K) != EOF){
  75.         char ch = getchar();
  76.         for(int i = 1; i <= N; i++){
  77.             while(ch == ' ' || ch == '/n')ch = getchar();
  78.             int x = 0;
  79.             while(ch != ' ' && ch != '/n'){
  80.                 x = x * 10 + ch - '0';
  81.                 ch = getchar();    
  82.             }
  83.             for(int j = 0; j < K; j++){
  84.                 node[i].bits[j] = 1 & (x >> j);    
  85.             }
  86.             node[i].idx = i;
  87.         }
  88.         memset(&node[0], 0, sizeof(node[0]));
  89.         for(int i = 1; i <= N; i++)
  90.             for(int j = 0; j < K; j++)
  91.                 node[i].bits[j] += node[i-1].bits[j];
  92.         for(int i = N; i >= 0; i--)
  93.             for(int j = K-1; j >= 0; j--)
  94.                 node[i].bits[j] -= node[i].bits[0];
  95.                 
  96.         
  97.         /*for(int i = 0; i < N; i++){
  98.             for(int j = 0; j < K; j++)
  99.                 printf("%d ", node[i].bits[j]);
  100.             printf("/n");    
  101.         }
  102.         printf("/n"); */
  103.         //
  104.         //      13248K  407MS    快排 
  105.         //
  106.         sort(node, node + N + 1);
  107.         int min_n = 1 << 28, max_n = 0, ans = 0;
  108.         for(int i = 1; i <= N; i++){
  109.             if(node[i] == node[i-1]){
  110.                 int min_t = min(node[i].idx, node[i-1].idx);
  111.                 int max_t = max(node[i].idx, node[i-1].idx);
  112.                 if(min_n > min_t)min_n = min_t;
  113.                 if(max_n < max_t)max_n = max_t;
  114.                 if(ans < max_n - min_n)ans = max_n - min_n;    
  115.             }else{
  116.                 min_n = 1 << 28;
  117.                 max_n = 0;    
  118.             }
  119.         }
  120.         printf("%d/n", ans);
  121.         /
  122.         /
  123.         
  124.         /*
  125.         /
  126.         //        29828K    1797MS     map
  127.         /
  128.         map<Node, int> mym;
  129.         vector<int> l[MAX];
  130.         int j = 0;
  131.         for(int i = 0; i <= N; ++i) {
  132.             if(mym.find(node[i]) == mym.end()) 
  133.                 mym[node[i]] = j++;
  134.             l[mym[node[i]]].push_back(i);
  135.         }
  136.         int res = 0;
  137.         for(int i = 0; i < j; ++i) {
  138.             int min = 123456789, max = -1;
  139.             for(int k = 0; k < l[i].size(); ++k) {
  140.                 if(l[i][k] > max) max = l[i][k];
  141.                 if(l[i][k] < min) min = l[i][k];
  142.             }
  143.             if(max - min > res) res = max - min;
  144.         }
  145.         printf("%d/n", res);
  146.         //
  147.         //
  148.         */
  149.     }
  150.     return 0;    
  151. }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值