Thứ Hai, 26 tháng 11, 2012

Problem Restoring IPv6

Link: http://codeforces.com/problemset/problem/250/B

B. Restoring IPv6
time limit per test
2 seconds
memory limit per test
256 megabytes
input
standard input
output
standard output
An IPv6-address is a 128-bit number. For convenience, this number is recorded in blocks of 16 bits in hexadecimal record, the blocks are separated by colons — 8 blocks in total, each block has four hexadecimal digits. Here is an example of the correct record of a IPv6 address: "0124:5678:90ab:cdef:0124:5678:90ab:cdef". We'll call such format of recording an IPv6-address full.
Besides the full record of an IPv6 address there is a short record format. The record of an IPv6 address can be shortened by removing one or more leading zeroes at the beginning of each block. However, each block should contain at least one digit in the short format. For example, the leading zeroes can be removed like that: "a56f:00d3:0000:0124:0001:f19a:1000:0000 → "a56f:d3:0:0124:01:f19a:1000:00". There are more ways to shorten zeroes in this IPv6 address.
Some IPv6 addresses contain long sequences of zeroes. Continuous sequences of 16-bit zero blocks can be shortened to "::". A sequence can consist of one or several consecutive blocks, with all 16 bits equal to 0.
You can see examples of zero block shortenings below:
  • "a56f:00d3:0000:0124:0001:0000:0000:0000 → "a56f:00d3:0000:0124:0001::";
  • "a56f:0000:0000:0124:0001:0000:1234:0ff0 → "a56f::0124:0001:0000:1234:0ff0";
  • "a56f:0000:0000:0000:0001:0000:1234:0ff0 → "a56f:0000::0000:0001:0000:1234:0ff0";
  • "a56f:00d3:0000:0124:0001:0000:0000:0000 → "a56f:00d3:0000:0124:0001::0000";
  • "0000:0000:0000:0000:0000:0000:0000:0000 →  "::".
It is not allowed to shorten zero blocks in the address more than once. This means that the short record can't contain the sequence of characters "::" more than once. Otherwise, it will sometimes be impossible to determine the number of zero blocks, each represented by a double colon.
The format of the record of the IPv6 address after removing the leading zeroes and shortening the zero blocks is called short.
You've got several short records of IPv6 addresses. Restore their full record.
Input
The first line contains a single integer n — the number of records to restore (1 ≤ n ≤ 100).
Each of the following n lines contains a string — the short IPv6 addresses. Each string only consists of string characters "0123456789abcdef:".
It is guaranteed that each short address is obtained by the way that is described in the statement from some full IPv6 address.
Output
For each short IPv6 address from the input print its full record on a separate line. Print the full records for the short IPv6 addresses in the order, in which the short records follow in the input.
Sample test(s)
input
6
a56f:d3:0:0124:01:f19a:1000:00
a56f:00d3:0000:0124:0001::
a56f::0124:0001:0000:1234:0ff0
a56f:0000::0000:0001:0000:1234:0ff0
::
0ea::4d:f4:6:0
output
a56f:00d3:0000:0124:0001:f19a:1000:0000
a56f:00d3:0000:0124:0001:0000:0000:0000
a56f:0000:0000:0124:0001:0000:1234:0ff0
a56f:0000:0000:0000:0001:0000:1234:0ff0
0000:0000:0000:0000:0000:0000:0000:0000
00ea:0000:0000:0000:004d:00f4:0006:0000


Thuật toán: Cài đặt theo mô tả bài toán.
Duyệt từ cuối dòng đến đầu dòng, làm các công việc sau:

  • Đếm số làn xuất hiện kí tự ':'.
  • Tại vị trí xuất hiện kí tự ':', ghi nhận số lượng của kí tự nằm giữa hai kí tự ':'....':'.
  • Quét lại đầu dòng để in ra.
Code:

/*
Coder : Nguyen Duc Tam
*/
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<set>
#include<vector>
#include<utility>
#include<map>
#include<list>
#include<queue>
#include<deque>
#include<stack>
#include<cstring>
#include<string>
#include<cmath>
#include<cstdlib>
#include<iomanip>
#include<ctime>

using namespace std;

#define REP(i, start, end, step) for(int i = start; i < end; i += step)
#define DOWN(i, start, end, step) for(int i = start; i > end; i -= step)
#define FOR(it,c) for(__typeof((c).begin()) it = (c).begin(); it != (c).end(); it++)
#define ALL(c) (c).begin(), (c).end()
#define SZ(x) ((int)(x).size())
#define X first
#define Y second

#define L(x,i) ((x) << (i))
#define R(x,i) ((x) >> (i))
#define AND(a,b) ((a) & (b))
#define OR(a,b) ((a) | (b))
#define XOR(a,b) ((a) ^ (b))
#define NOT(a) (~(a))
#define SB(x,i) (OR((x), L(1, (i)))) // x | 1 << i
#define CB(x,i) (AND((x),NOT(L(1,(i))))) // x & ~(1 << i)
#define TB(x,i) (AND((x), L(1,(i)))) // x & (1 << i)

#define FILL(a,val) memset(a,val,sizeof(a));
#define INIT(a,l,r,val) REP(i,l,r,1) (a)[i] = val;
#define DIG(c) (int)((c) - '0')
#define CHR(c) (char)((c) + '0')
#define LOW(c) (char)((c) + 32)
#define UPP(c) (char)((c) - 32)

#define EPS 1e-7
#define OO 1000000005
#define N 100005

const int DAY[13] = {-1,31,29,31,30,31,30,31,31,30,31,30,31};
const int dx4[4] = {};
const int dy4[4] = {};
const int dx8[8] = {};
const int dy8[8] = {};


typedef pair<int,int> II;
typedef pair<II,int> D;
typedef long long LL;
typedef unsigned long long ULL;
typedef unsigned char UC;

vector<int>::iterator it, low, up; // using FOR, lower_bound, upper_bound
pair<vector<int>,vector<int> > bound; // using function equal_range(first, last, x)

int n,_count,next[35],pos;
string s,res;

int main()
{
#define Off  true
if(Off)
{
freopen("input.txt","r",stdin);
freopen("output.txt","w",stdout);
}
cin >> n;
REP(i,0,n,1)
{
cin >> s;
res = "";
_count = 0;
pos = s.size();
INIT(next,0,33,0);

DOWN(ii,s.size() - 1,-1,1)
if(s[ii] == ':')
{
next[ii] = pos;
pos = ii;
_count++;
}

REP(ii,pos,4,1)
res = res + "0";

REP(ii,0,s.size(),1)
if(s[ii] == ':')
{
if(s[ii+1] == ':')
{
while(++_count <= 8)
{
res = res + ":0000";
}
}
else
{
res = res + ":";
REP(k,next[ii] - ii,5,1) res = res + "0";
}
}
else
res = res + s[ii];
cout << res << endl;
}
return 0;
}




Không có nhận xét nào:

Đăng nhận xét