24h購物| | PChome| 登入
2013-07-22 17:02:53| 人氣870| 回應0 | 上一篇 | 下一篇

[UVA][模擬] 1064 - Network

推薦 0 收藏 0 轉貼0 訂閱站台

A packet-switching network handles information in small units, breaking long messages into multiple packets before routing. Although each packet may travel along a different path, and the packets comprising a message may arrive at different times or out of order, the receiving computer reassembles the original message correctly.

The receiving computer uses a buffer memory to hold packets that arrive out of order. You must write a program that calculates the minimum buffer size in bytes needed to reassemble the incoming messages when the number of messages (N ), the number of packets (M ), the part of the messages in each packet, the size of each message, and the order of the incoming packets are given.

When each packet arrives, it may be placed into the buffer or moved directly to the output area. All packets that are held in the buffer are available to be moved to the output area at any time. A packet is said to ``pass the buffer" when it is moved to the output area. A message is said to ``pass the buffer" when all of its packets have passed the buffer.

The packets of any message must be ordered so the data in the sequence of packets that pass the buffer is in order. For example, the packet containing bytes 3 through 5 of a message must pass the buffer before the packet containing bytes 6 through 10 of the same message. Messages can pass the buffer in any order, but all packets from a single message must pass the buffer consecutively and in order (but not necessarily at the same time). Note that unlike actual buffering systems, the process for this problem can look ahead at all incoming packets to make its decisions.

The packets consist of data and header. The header contains three numbers: the message number, the starting byte number of data in the packet, and the ending byte number of data in the packet respectively. The first byte number in any message is 1.

For example, the figure below shows three messages (with sizes of 10, 20, and 5 bytes) and five packets. The minimum buffer size for this example is 10 bytes. As they arrive, packet #1 and packet #2 are stored in the buffer. They occupy 10 bytes. Then packet #3 passes the buffer directly. Packet #4 passes the buffer directly and then packet #2 exits the buffer. Finally, packet #5 passes the buffer directly and packet #1 exits the buffer.

epsfbox{p3808.eps}

Input 

The input file contains several test cases. The first line of each test case contains two integers N (1$ le$N$ le$5) and M (1$ le$M$ le$1000) . The second line contains N integers that are the sizes of messages in bytes; the first number denotes the size of message #1, the second number denotes the size of message #2, and so on. Each of the following M lines describes a packet with three integers: the message number and the starting and ending byte numbers of data in the packet. No packet contains more 64 bytes of data.

The last test case is followed by a line containing two zeroes.

Output 

For each test case, print a line containing the test case number (beginning with 1) followed by the minimum buffer size in bytes required to reassemble the original messages. Put a blank line after the output for each test case. Use the format of the sample output.

Sample Input 

3 3 
5 5 5 
1 1 5 
2 1 5 
3 1 5 
3 5 
10 20 5 
2 16 20 
1 6 10 
3 1 5 
1 1 5 
2 1 15 
0 0

Sample Output 

Case 1: 0 

Case 2: 10

題目解法:
題目給定每個封包不超過 64 bytes => 得到 message 不超過 64000 bytes
由於要自己決定哪個封包要先處理,因此要窮舉 n!,然後在模擬整個過程。

題目說明訊息要依序完成,而每個訊息內部的封包要依序完成。
那麼基於 greedy 的想法,能從 buffer 清出就盡量清出,最後比較其最大的 buffer size 中的最小。

#include <stdio.h>
#include <string.h>
#include <iostream>
#include <algorithm>
using namespace std;
int buffer[5][65536][2] = {};
int main() {
int n, m, cases = 0;
int len[10], i;
while(scanf("%d %d", &n, &m) == 2 && n) {
int A[10];
for(i = 0; i < n; i++) {
scanf("%d", &len[i]);
A[i] = i;
}
int msg[1005], l[1005], r[1005];
int ret = 0xfffffff;
for(i = 0; i < m; i++) {
scanf("%d %d %d", &msg[i], &l[i], &r[i]);
msg[i]--;
}
do {
for(i = 0; i < n; i++)
memset(buffer[i], 0, (len[i]+10)*4*2);
int bufsize = 0, sub = 0;
int order[5] = {1,1,1,1,1};
int accept = 0;
for(i = 0; i < m; i++) {
int ll = l[i], rr = r[i], kmsg = msg[i];
if(order[kmsg] == ll && kmsg == A[accept]) {
order[kmsg] = rr+1;
while(buffer[kmsg][order[kmsg]][0]) {
bufsize -= buffer[kmsg][order[kmsg]][1]-order[kmsg];
order[kmsg] = buffer[kmsg][order[kmsg]][1];
}// pop this message
while(accept+1 < n && order[A[accept]] == len[A[accept]]+1) {//pop next message
accept++;
int kmsg = A[accept];
while(buffer[kmsg][order[kmsg]][0]) {
bufsize -= buffer[kmsg][order[kmsg]][1]-order[kmsg];
order[kmsg] = buffer[kmsg][order[kmsg]][1];
}
}
} else {
bufsize += rr-ll+1;
buffer[kmsg][ll][0] = 1;
buffer[kmsg][ll][1] = rr+1;
}
sub = max(sub, bufsize);
if(sub >= ret) break;//impossible
}
ret = min(ret, sub);
} while(next_permutation(A, A+n));
printf("Case %d: %d\n\n", ++cases, ret);
}
return 0;
}

台長: Morris
人氣(870) | 回應(0)| 推薦 (0)| 收藏 (0)| 轉寄
全站分類: 不分類 | 個人分類: UVA |
此分類下一篇:[UVA][模擬] 380 - Call Forwarding
此分類上一篇:[UVA] 1047 - Zones

是 (若未登入"個人新聞台帳號"則看不到回覆唷!)
* 請輸入識別碼:
請輸入圖片中算式的結果(可能為0) 
(有*為必填)
TOP
詳全文