1640. 万能遥控器
★ 输入文件:remote.in 输出文件:remote.out 简单对比
时间限制:1 s 内存限制:256 MB
【题目描述】
Z镇的恒恒有着各种各样的机器人。为了控制所有的机器人,恒恒托别人造了一个万能遥控器。只要向遥控器输入一个机器人的编号,就能遥控这个机器人。可是有一天,恒恒发现他的机器人实在太多了(而且越来越多),以至于使用IPV4协议都不够唯一地标记每个机器人。后来,恒恒听说IPV6协议拥有近无穷个地址,于是他就想用IPV6协议来为机器人编号。不过,完整的IPV6地址很长(有39个字符),手工输入很费时间,所以IPV6有一套简化的机制。现在,恒恒给了你一些IPV6地址,请你编写程序,将它们转换为完整的地址吧!
IPV6的地址定义如下:
IPV6的地址有128位,以16位为一分组,每个16位分组写成4个十六进制数,中间用冒号分隔,称为冒号分十六进制格式。
例如:21DA:00D3:0000:2F3B:02AA:00FF:FE28:9C5A是一个完整的IPV6地址。
IPV6地址中每个16位分组中的前导零位可以去除做简化表示,但每个分组必须至少保留一位数字。如上例中的地址,去除前导零位后可写成
21DA:D3:0:2F3B:2AA:FF:FE28:9C5A
某些地址中可能包含很长的零序列,为进一步简化表示法,还可以将冒号十六进制格式中的相邻的连续零位合并,用双冒号“::”表示。“::”符号在一个地址中只能出现一次,该符号也能用来压缩地址中前部和尾部相邻的连续零位,例如地址1080:0:0:0:8:800:200C:417A,0:0:0:0:0:0:0:1,0:0:0:0:0:0:0:0分别可表示为压缩格式1080::8:800:200C:417A,::1,::。
【输入格式】
第1行为一个正整数n,表示接下来将有n个地址。
将下来有n行,每行一个非空字符串,表示一个地址。
【输出格式】
一共n行,每行一个字符串。对每个输入的字符串,如果符合IPV6标准,则输出其对应的完整的IPV6地址,否则,输出INVALID。
【样例输入】
4
1080::8:800:200C:417A
::1
::
1234567890ABCDEF
【样例输出】
1080:0000:0000:0000:0008:0800:200C:417A
0000:0000:0000:0000:0000:0000:0000:0001
0000:0000:0000:0000:0000:0000:0000:0000
INVALID
【提示】
输入和输出文件只包含数字、大写字母、冒号(:英文的)和换行符。输入每行不超过39个字符。
【来源】
在此键入。
1 #include<cstdio> 2 #include<cstring> 3 #include<iostream> 4 #include<algorithm> 5 using namespace std; 6 void Emine(){ 7 freopen("remote.in","r",stdin); 8 freopen("remote.out","w",stdout); 9 } 10 int read(){ 11 int x=0,f=1;char ch=getchar(); 12 while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();} 13 while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();} 14 return x*f; 15 } 16 int n; 17 void work(){ 18 string a;cin>>a; 19 int mh=0,smh=0,len=a.length(),id; 20 if((a[0]==':'&&a[1]!=':')||(a[len-2]!=':'&&a[len-1]==':')){printf("INVALID\n");return;} 21 for(int i=0;i<len;i++){ 22 if(a[i]!=':'&&a[i+1]!=':'&&a[i+2]!=':'&&a[i+3]!=':'&&a[i+4]!=':'&&(i+4)<=len-1){printf("INVALID\n");return;} 23 if(a[i]==':'&&a[i+1]==':'&&a[i+2]==':'){printf("INVALID\n");return;} 24 if(a[i]==':'&&a[i+1]==':'&&a[i-1]=='0'&&a[i+2]=='0'){printf("INVALID\n");return;} 25 //if(a[i]==':'&&a[i-1]=='0'&&a[i+1]=='0'&&a[i+2]=='0'&&a[i-2]!='0'){printf("INVALID\n");return;} 26 if(a[i]==':'&&a[i-1]!=':'&&a[i+1]!=':')mh++; 27 if(a[i]==':'&&a[i+1]==':'){smh++;id=i;i+=2;} 28 } 29 int smh0=7-mh-2*smh; 30 if((mh<7&&smh==0)||smh>1||mh>=8||(mh+smh)>=8||(mh==6&&smh>=1)||(mh==5&&id!=0&&id!=(len-2))){printf("INVALID\n");return;} 31 int last=0,i=0; 32 while(i<len){ 33 if(a[i]!=':'&&a[i+1]==':'||i==len-1){ 34 if(i-last+1>4){printf("INVALID\n");return;} 35 if(i-last+1==4){for(int j=last;j<=i;j++)cout<<a[j];} 36 else{ 37 for(int j=1;j<=(4-(i-last)-1);j++)printf("0"); 38 for(int j=last;j<=i;j++)cout<<a[j]; 39 } 40 if(a[i+2]==':'){last=i+3;printf(i==(len-1)?"":":");} 41 else{last=i+2;printf(i==(len-1)?"":":");} 42 } 43 if(a[i]==':'&&a[i+1]==':'){ 44 //printf(":"); 45 if(i==0)for(int j=1;j<=smh0+2;j++)printf("0000:"); 46 else for(int j=1;j<=smh0+1;j++)printf("0000:"); 47 last=i+2; 48 } 49 i++; 50 } 51 printf("\n"); 52 } 53 int main(){ 54 //freopen("1.in","r",stdin); 55 Emine(); 56 n=read(); 57 while(n--)work(); 58 return 0; 59 }
1641. 源石
★ 输入文件:yuanshi.in 输出文件:yuanshi.out 简单对比
时间限制:1 s 内存限制:256 MB
【题目描述】
很久以前,在遥远星系中,有一颗以源石作为基础能量的行星。源石中蕴含有巨大的能量,平时为了防止能量外泄必须将源石保存在特定的矿井中,每个矿井中只能保存一块源石。源石的保存要求很高,不同种类的源石必须分开保存,并且要留有足够的安全距离,以防止其互相干扰爆炸。
源天师叶凡是这颗行星中精通源术的大师,他掌握着N[1..200000]个用来保存源石的矿井,这些矿井之间由M[1..200000]条路连接,通过这些路可以从任意一个矿井到达另外一个,每条路有一个范围为[1..1000000]的路径长度,每两个矿井之间最多有一条路连接。
现在源天师叶凡的每个矿井里都保存有一颗源石,这些源石一共k[1..N]种。某天,叶凡接到源天师委员会的命令,需要调出Q个源石用来打造一尊秘密武器,同时调入Q个新的源石。叶凡一般采用的方法是调出一个源石之后,立即在原矿井中放入一块新的源石,这个操作称作置换。因为源石的危险性,在每次置换后,叶凡希望知道安放有不同种类源石的矿井之间的最短距离,即在所有安放有不同种类源石的矿井之间寻找哪两个矿井是最近的。理想情况下,这个距离要足够大,最起码保证安全距离,以防止不同种类的源石之间发生爆炸。所有矿井中至少有两种不同的源石。
30%的输入,连接每个矿井至多有10条路径。
【输入格式】
第一行有4个整数,N,M,K,Q。其中N表示矿井数,K表示源石种类数量。接下来的M行用来表示路径,有三个整数组成,分别表示两个矿井的编号,及它们之间的路径长度。接下来的一行表示最初存放在N个矿井中的源石种类编号,有N个范围为[1..K]的整数。最后的Q行有两个数A,B,表示Q次置换操作,将矿井A中的源石换成类别为B的源石,1<=Q<=200000。
【输出格式】
每次置换后,打印安放有不同种类源石的矿井之间的最短路径的长度。
【样例输入】
3 2 3 4
1 2 3
2 3 1
1 1 2
3 3
2 3
1 2
2 2
【样例输出】
1
3
3
1
【提示】
在此键入。
【来源】
在此键入。
1 #include<cstdio> 2 #include<cstring> 3 #include<iostream> 4 #include<algorithm> 5 #define maxn 200005 6 #define inf 0x3f3f3f3f 7 using namespace std; 8 void Emine(){ 9 freopen("yuanshi.in","r",stdin); 10 freopen("yuanshi.out","w",stdout); 11 } 12 int read(){ 13 int x=0,f=1;char ch=getchar(); 14 while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();} 15 while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();} 16 return x*f; 17 } 18 struct node{int u,v,w;}e[maxn]; 19 bool cmp(node a,node b){return a.w<b.w;} 20 int col[maxn],fir[maxn];//fir[i]记录每一个点第一次出现的边 21 int n,m,k,q,now; 22 int main(){ 23 Emine(); 24 n=read(),m=read(),k=read(),q=read(); 25 for(int i=1;i<=n;i++)fir[i]=inf; 26 for(int i=1;i<=m;i++){e[i].u=read(),e[i].v=read(),e[i].w=read();} 27 sort(e+1,e+m+1,cmp); 28 for(int i=1;i<=m;i++){ 29 fir[e[i].u]=min(i,fir[e[i].u]); 30 fir[e[i].v]=min(i,fir[e[i].v]); 31 } 32 for(int i=1;i<=n;i++)col[i]=read(); 33 for(int i=1;i<=m;i++) 34 if(col[e[i].u]!=col[e[i].v]){now=i;break;} 35 for(int i=1;i<=q;i++){ 36 int x=read(),y=read(); 37 col[x]=y; 38 if(fir[x]>now)printf("%d\n",e[now].w); 39 else{ 40 for(int j=fir[x];j<=m;j++) 41 if(col[e[j].u]!=col[e[j].v]){now=j;break;} 42 printf("%d\n",e[now].w); 43 } 44 } 45 return 0; 46 }
1645. 创世纪
★ 输入文件:genesis.in 输出文件:genesis.out 简单对比
时间限制:2 s 内存限制:256 MB
【题目描述】
上帝手中有着N 种被称作“世界元素”的东西,现在他要把它们中的一部分投放到一个新的空间中去以建造世界。每种世界元素都可以限制另外一种世界元素,所以说上帝希望所有被投放的世界元素都有至少一个没有被投放的世界元素能够限制它,这样上帝就可以保持对世界的控制。
由于那个著名的有关于上帝能不能制造一块连自己都不能举起的大石头的二律背反命题,我们知道上帝不是万能的,而且不但不是万能的,他甚至有事情需要找你帮忙——上帝希望知道他最多可以投放多少种世界元素,但是他只会O(2^N) 级别的算法。虽然上帝拥有无限多的时间,但是他也是个急性子。你需要帮助上帝解决这个问题。
【输入格式】
第一行是一个整数N,表示世界元素的数目。
第二行有 N 个整数A1, A2, …, AN。Ai 表示第i 个世界元素能够限制的世界元素的编号。
【输出格式】
一个整数,表示最多可以投放的世界元素的数目。
【样例输入】
6
2 3 1 3 6 5
【样例输出】
3
【提示】
样例说明
选择2、3、5 三个世界元素即可。分别有1、4、6 来限制它们。
数据范围与约定
对于30% 的数据,N≤10。
对于60% 的数据, N≤10^5。
对于 100% 的数据,N≤10^6,1≤Ai≤N,Ai≠i。
各个测试点2s
【来源】
在此键入。
1 #include<cstdio> 2 #include<queue> 3 #include<cstring> 4 #include<iostream> 5 #include<algorithm> 6 #define maxn 1000005 7 #define inf 0x3f3f3f3f 8 using namespace std; 9 void Emine(){ 10 freopen("genesis.in","r",stdin); 11 freopen("genesis.out","w",stdout); 12 } 13 int read(){ 14 int x=0,f=1;char ch=getchar(); 15 while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();} 16 while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();} 17 return x*f; 18 } 19 int n,v[maxn],vis[maxn],in[maxn],ans=0; 20 int main(){ 21 Emine(); 22 n=read(); 23 for(int i=1;i<=n;i++){v[i]=read();in[v[i]]++;} 24 queue<int> q; 25 for(int i=1;i<=n;i++){if(!in[i])q.push(i);} 26 while(!q.empty()){ 27 int u=q.front();q.pop();vis[u]=1; 28 if(!vis[v[u]]){ 29 vis[v[u]]=1; 30 ans++; 31 if(--in[v[v[u]]]==0)q.push(v[v[u]]); 32 } 33 } 34 for(int i=1;i<=n;i++){ 35 if(!vis[i]){ 36 int tmp=1,id=i; 37 vis[i]=1; 38 while(v[id]!=i){ 39 id=v[id]; 40 vis[id]=1; 41 tmp++; 42 } 43 ans+=(tmp/2); 44 } 45 } 46 printf("%d\n",ans); 47 return 0; 48 }