模拟字符串处理
很暴力的方法,就是把能变成::的全部枚举一次,选最小的即可。。
#include <bits/stdc++.h>
#define INF 0x3f3f3f3f
#define full(a, b) memset(a, b, sizeof a)
#define __fastIn ios::sync_with_stdio(false), cin.tie(0)
#define pb push_back
using namespace std;
typedef long long LL;
inline int lowbit(int x){ return x & (-x); }
inline int read(){
int ret = 0, w = 0; char ch = 0;
while(!isdigit(ch)){
w |= ch == '-', ch = getchar();
}
while(isdigit(ch)){
ret = (ret << 3) + (ret << 1) + (ch ^ 48);
ch = getchar();
}
return w ? -ret : ret;
}
inline int lcm(int a, int b){ return a / __gcd(a, b) * b; }
template <typename A, typename B, typename C>
inline A fpow(A x, B p, C lyd){
A ans = 1;
for(; p; p >>= 1, x = 1LL * x * x % lyd)if(p & 1)ans = 1LL * x * ans % lyd;
return ans;
}
int _;
const string ch = "0123456789abcdef";
string s, t;
string calc(string &tmp){
bool flag = true;
string ret = "";
for(int i = 0; i < 4; i ++){
if(flag && tmp[i] == '0') continue;
if(tmp[i] != '0') flag = false;
ret.pb(tmp[i]);
}
if(ret.empty()) ret = "0";
return ret;
}
string rebuild(string &str){
int cnt = 0;
string ret = "";
for(auto &c: str){
if(c == ':') cnt ++;
else cnt = 0;
if(cnt <= 2) ret.pb(c);
}
return ret;
}
bool cmp(const string &a, const string &b){
if(a.size() != b.size()) return a.size() < b.size();
return a < b;
}
int main(){
//freopen("data.txt", "r", stdin);
__fastIn;
int cs = 0;
for(cin >> _; _; _ --){
cin >> s;
t.clear();
for(int i = 0; i < s.size(); i += 16){
string str = s.substr(i, 16);
string tmp = "";
int st = 0;
for(int j = 1; j <= 4; j ++){
int val = 1, sum = 0;
for(int k = st + 3; k >= st; k --){
sum += str[k] == '1' ? val : 0;
val <<= 1;
}
st += 4;
tmp.pb(ch[sum]);
}
tmp = calc(tmp);
t += tmp, t += ":";
}
vector<string> record, ans;
string cur = "";
for(int i = 0; i < t.size(); i ++){
if(t[i] == ':'){
record.pb(cur), cur.clear();
}
else cur += t[i];
}
for(int i = 0; i + 1 < record.size(); i ++){
if(record[i] == record[i + 1] && record[i] == "0"){
int k = 2;
while(i + k < record.size() && record[i] == record[i + k]) k ++;
k --;
string str = "";
for(int j = 0; j < record.size(); j ++){
if(j == i) str += "::", j += k;
else str += record[j];
str += ":";
}
str.pop_back();
str = rebuild(str);
ans.pb(str);
}
}
cout << "Case #" << ++cs << ": ";
if(ans.empty()){
cout << record[0];
for(int i = 1; i < record.size(); i ++){
cout << ":" << record[i];
}
cout << endl;
}
else{
cout << min_element(ans.begin(), ans.end(),
[](const string &a, const string &b){
if(a.size() != b.size()) return a.size() < b.size();
return a < b;
})->c_str() << endl;
}
}
return 0;
}