#C231109A. 万能遥控器
前言(Front talk)
$\qquad$这是一道大美女(bushi)
$\qquad$好像是首次打这种类似的模拟题,还是挺激动的。( •̀ ω •́ )✧
网址(Website)
题解(Solution)
几个注意点:
- $For(i,l,r)$ 里面不要加 $s.length()$ ,一定要换成定值 $len$ ,否则要出错。(是答案出错而不是报错,会凭空花费很多时间)
- 要去除非 $16$ 进制的字符
- 区间字符数不能大于 4 个
- 首个或结尾出现的单个冒号,不合法
- 没有 :: 作省略却不足 8 个 地址
- 一个单独的0分组不能使用 :: 省略
- 地址多于 8 个
- 省略的 0 需补全
- 结尾冒号省略
- 多测清空
代码(Code)
#include<bits/stdc++.h>
#include<vector>
#define For(i,l,r) for(int i=l;i<=r;i++)
#define Rof(i,l,r) for(int i=l;i>=r;i--)
using namespace std;
inline int input(){int x;return cin>>x,x;}
const int mao=8;
int n;
string s;
vector<char> jian[14];//区间
int tot;//记录区间个数
int rem;//记录双冒号的位置
void solve(string s){
//初始化
For(i,1,8) jian[i].clear();
rem=-1;tot=0;
int len=s.length();
//去除非 16 进制的字符
For(i,0,len-1){
if(!isdigit(s[i]) && (s[i]!=':' && s[i]!='A' && s[i]!='B' && s[i]!='C' && s[i]!='D' && s[i]!='E' && s[i]!='F')){
return cout<<"INVALID\n",void();
}
}
//找到 :: 的位置
For(i,0,len-2){
if(s[i]==s[i+1] && s[i]==':'){
if(rem!=-1) return cout<<"INVALID\n",void();//出现了多个 :: 或者出现了 :::
rem=i;
}
}
//每个区间
for(int i=0;i<len;){
while(i<len && s[i]==':') i++;
if(i>=len) break;//:: 冒号后的区间可能为空,舍去
tot++;//开新的区间
while(i<len && s[i]!=':'){
jian[tot].emplace_back(s[i]);
i++;
}if(jian[tot].size()>4) return cout<<"INVALID\n",void();//区间字符数大于 4 个
}
//特判首个或结尾出现的单个冒号,不合法
if(s[0]==':' && rem!=0) return cout<<"INVALID\n",void();
if(s[len-1]==':' && rem!=len-2) return cout<<"INVALID\n",void();
//没有 :: 作省略却不足 8 个 地址
if(rem==-1 && tot!=8) return cout<<"INVALID\n",void();
//一个单独的0分组不能使用 :: 省略
if(rem>=0 && 8-tot<=1) return cout<<"INVALID\n",void();
//地址多于 8 个
if(tot > 8) return cout<<"INVALID\n",void();
//输出
for(int i=0,k=1;i<len;){
if(i==rem){//如果是 ::
For(k,1,8-tot){
if(i+2==len && k==8-tot) cout<<"0000";//结尾冒号省略
else cout<<"0000:";
}i+=2;continue;
}while(i<len && s[i]==':') i++;//跳过 :
For(ss,1,4-jian[k].size()) cout<<'0';//省略的 0 需补全
for(auto c:jian[k]){
cout<<c;
i++;
}if(i<len)cout<<":";//结尾冒号省略
k++;//下一个区间
}cout<<'\n';return;
}
signed main(){
ios::sync_with_stdio(false),cin.tie(0),cout.tie(0);
string str("ipv6");
freopen((str+".in").c_str(),"r",stdin);
freopen((str+".out").c_str(),"w",stdout);
cin>>n;while(n--){
cin>>s;
solve(s);
}return 0;
}
后续(Ending)
本来准备放题解代码的,结果发现题解代码比我的还丑。`(>﹏<)′