POJ1055 BULK MAILING

题目来源:http://poj.org/problem?id=1055

题目大意:

  每封信都有一个zip-code, 由5位数字构成,可以通过将zip-code相同或相近的信件打包来节省成本。打包规则是:5位数字完全相同的10-15封可组成一个包(5-digit bundles),或者将前3位数字相同的信件打包,同样10-15份一包(3-digit bundles)。优先分配为5-digit bundles, 其次3-digit bundles。不能被打包的信件为first class letters。要求输出打包方案。

输入:没行一个zip-code,但并非每个都是合法的。合法的zip-code恰好由5位数字组成,不能全为0.

输出:按上述要求输出打包方案,格式见输出,合法的bundles和letters需要按数字大小顺序输出。。


Sample Input

95864
95864
95864
95867
95920
9j876
95616                 
95616                 
95747                 
95814                 
95818                 
95818                 
8976
95818                 
95818
95819                 
95819                 
00000
95819                 
95819                 
95819
95819                 
95819                 
95825
95825
95825
95825
95825
95826
95826
95826
95826
95826
95826
95827
8976
95833
95833
95833
95833
95819                 
95819
95819
95819
95833
95833
95833
95864
95864
95864
123456
95864
95864
95864
95864

Sample Output

ZIP         LETTERS     BUNDLES

95819          11           1
95864          10           1

958xx          25           2

95616           2           0
95747           1           0
95920           1           0

TOTALS         50           4

INVALID ZIP CODES

9j876
8976
00000
123456

本题虽在POJ的第一版,但是却人气颇低..确实不太有意思, 主要思想就是桶排序。

输出格式非常坑人,很容易错,题目描述得也不是特别清楚,最后的非法zip-code需要判重且按出现顺序输出。按照提述规则,似乎有可能出现多解的情况,但是测试数据没有太***难,invalid zip-code的长度最长只到6,zip-code最高位不为0,用最简单的策略(对于一些比较偏的case可能不能过的)也可以AC。所以,这样的题随便看看就好了..

  1 ////////////////////////////////////////////////////////////////////
  2 //        POJ1055 BULK MAILING
  3 //        Memory: 1212K        Time: 0MS
  4 //        Language: C++        Result : Accepted
  5 ///////////////////////////////////////////////////////////////////
  6 
  7 #include <cstdio>
  8 #include <string>
  9 //#include <algorithm>
 10 
 11 using namespace std;
 12 
 13 struct Bundle { 
 14     int letter_cnt, bun_cnt; 
 15 };
 16 
 17 Bundle buns[100000];
 18 char buffer[10], invalid_record[100000][10];
 19 int invalid_cnt, zip_cnt[100000], total_letters, total_buns;
 20 
 21 bool M[100000];
 22 
 23 bool validity_check(char buffer[]){
 24     
 25     //位数检查
 26     if (strlen(buffer) != 5) {
 27         return false;
 28     }
 29 
 30     //数字检查
 31     for (int i = 0; i < 5; i++) {
 32         if (buffer[i] < '0' || buffer[i] > '9') {
 33             return false;
 34         }
 35     }
 36 
 37     //全0检查
 38     bool flag = true;
 39     for (int i = 0; i < 5; ++i) {
 40         if (buffer[i] != '0') {
 41             flag = false;
 42             break;
 43         }
 44     }
 45     if (flag) {
 46         return false;
 47     }
 48     return true;
 49 }
 50 
 51 void process1(void) {
 52 
 53     //同5位10份以上打包
 54     for (int i = 10000; i <= 99999; ++i) {
 55         if (zip_cnt[i] >= 10){
 56             while (zip_cnt[i] >= 15) {
 57                 buns[i].letter_cnt += 15;
 58                 ++buns[i].bun_cnt;
 59                 total_letters += 15;
 60                 ++total_buns;
 61                 zip_cnt[i] -= 15;
 62             }
 63             if (zip_cnt[i] >= 10) {
 64                 buns[i].letter_cnt += zip_cnt[i];
 65                 ++buns[i].bun_cnt;
 66                 total_letters += zip_cnt[i];
 67                 ++total_buns;
 68                 zip_cnt[i] = 0;
 69             }
 70         }
 71     }
 72 
 73     //按序输出
 74     printf("ZIP         LETTERS     BUNDLES\n");
 75     puts("");
 76     for (int i = 10000; i <= 99999; ++i) {
 77         if (buns[i].letter_cnt != 0) {
 78             printf("%d%12d%12d\n", i, buns[i].letter_cnt, buns[i].bun_cnt);
 79         }
 80     }
 81     puts("");
 82 
 83     //清空三位数的桶
 84     for (int i = 100; i <= 999; ++i) {
 85         buns[i].letter_cnt = buns[i].bun_cnt = 0;
 86     }
 87 }
 88 
 89 void process2(void) {
 90 
 91     //同3位10份以上打包
 92     for (int i = 100; i <= 999; ++i) {
 93         int temp[100][2];
 94         int cnt = 0, letter_cnt = 0;
 95         for (int j = 0; j <= 99; ++j) {
 96             int num = i * 100 + j;
 97             if (zip_cnt[num] > 0) {
 98                 temp[cnt][0] = num;
 99                 temp[cnt][1] = zip_cnt[num];
100                 letter_cnt += zip_cnt[num];
101                 zip_cnt[num] = 0;
102                 ++cnt;
103             }
104         }
105         while (letter_cnt >= 15) {
106             ++buns[i].bun_cnt;
107             ++total_buns;
108             buns[i].letter_cnt += 15;
109             total_letters += 15;
110             letter_cnt -= 15;
111         }
112         if (letter_cnt >= 10) {
113             ++buns[i].bun_cnt;
114             ++total_buns;
115             buns[i].letter_cnt += letter_cnt;
116             total_letters += letter_cnt;
117             letter_cnt = 0;
118         }
119         while (letter_cnt > 0) {
120             if (temp[cnt - 1][1] >= letter_cnt) {
121                 zip_cnt[temp[cnt - 1][0]] += letter_cnt;
122                 break;
123             } else {
124                 zip_cnt[temp[cnt - 1][0]] += temp[cnt - 1][1];
125                 letter_cnt -= temp[cnt - 1][1];
126                 --cnt;
127             }
128         }
129         if (buns[i].letter_cnt > 0) {
130             printf("%dxx%12d%12d\n", i, buns[i].letter_cnt, buns[i].bun_cnt);
131         }
132     }
133     puts("");
134 }
135 
136 void process3(void) {
137     //first class 输出
138     for (int i = 10000; i <= 99999; ++i) {
139         if (zip_cnt[i] > 0){
140             printf("%d%12d%12d\n", i, zip_cnt[i], 0);
141             total_letters += zip_cnt[i];
142         }
143     }
144     puts("");
145 }
146 
147 void output_invalid(void) {
148     //非法zip-code输出
149     printf("INVALID ZIP CODES\n\n");
150     for (int i = 0; i < invalid_cnt; ++i) {
151         bool flag = true;
152         for (int j = 0; j < i; ++j) {
153             if (strcmp(invalid_record[i], invalid_record[j]) == 0) {
154                 flag = false;
155             }
156         }
157         if (flag) {
158             printf("%s\n", invalid_record[i]);
159         }
160     }
161 
162 }
163 int main(void) {
164      invalid_cnt = 0;
165     while (scanf("%s", buffer) != EOF) {
166         if (validity_check(buffer)) {
167 
168             //桶排序
169             int num = 0;
170             for (int i = 0; i < 5; ++i) {
171                 num = num * 10 + buffer[i] - '0';
172             }
173             ++zip_cnt[num];
174         } else {
175             strcpy(invalid_record[invalid_cnt], buffer);
176             ++invalid_cnt;
177         }
178     }
179 
180     process1();
181     process2();
182     process3();
183     printf("TOTALS%11d%12d\n\n", total_letters, total_buns);
184     output_invalid();
185     
186     return 0;
187 }
View Code
posted @ 2013-10-24 21:11  小菜刷题史  阅读(536)  评论(0编辑  收藏  举报