郑州轻工业学院第八届玲珑杯校赛题解

Description

蛤玮最近学习了关于ip的知识,于是他迫不及待的想把新知识传授给她的妹子.蛤玮的妹子随便写下了一个字符串,蛤玮现在要告诉她这个字符串是不是一个合法的ip地址.
为简单考虑,仅考虑ipv4的情况,即合法ip为形同"a1.a2.a3.a4",且0<=ai<=255。
Input


第一行为一个整数T(1<=T<=20),代表数据组数。接下来T行每行一个字符串,其中不包含空格,Tab以及回车,长度不超过50。

Output

若合法,输出"Yes",否则输出"No"(不包含引号)。


Sample Input

210.105.240.51f.a.t.e


Sample Output

YesNo


HINT


我们认为010.105.240.051是合法的。

此题需要考虑的情况有连续出现两个..的情况、首尾都是..的情况、两点之间出现非数字的情况(也有可能不是字母是其他的字符)、两点之间数字个数大于3的情况、小数点的个数不等于3的情况,如此应该就好了,如果还有我没考虑的情况请联系我……

如下代码:


#include<iostream>
#include<cstdio>
#include<cstring>
#include<ctype.h>
using namespace std;

int main(){
	int t;
	while(scanf("%d", &t)!=EOF){
		while(t--){
			string str;
			bool flag=true;
			int sum=0,node=0,p=0,i;
			cin>>str;
			int len=str.size();
			if(str[0]=='.' || str[len-1]=='.')	{
				puts("No");continue;
			}
			for(i=0; i<len; ++i){
				if(str[i]!='.' && !isdigit(str[i])/*!(str[i]>='0'&&str[i]<='9')*/){
					flag=false;break;
				}
				if(str[i] == '.' && str[i+1] == '.'){
					flag=false;break;
				}
				if(str[i]=='.'){
					sum=node=0;
					p++;//判断小数点个数 
				}
				else if(str[i]!='.' && isdigit(str[i])/*str[i]>='0'&&str[i]<='9'*/ ){
					++node;//判断数字个数 
					sum=sum*10+(str[i]-'0');
				}
				if(sum<0 ||sum>255||node>3){
					flag=false;break;
				}	
			}
			if(flag && p==3 && i==len)
				puts("Yes");
			else
				puts("No");
		}
	}
	return 0;
}


Description

蛤玮的妹子过生日,蛤玮把千辛万苦挑选出来的礼物送到了妹子面前,然而妹子非常生气,因为妹子要的是化妆套装,而蛤玮买了一套水彩铅笔,更可气的是这些铅笔像是二手的,因为他们不是一样长!
为了惩罚蛤玮,妹子说"我有强迫症,受不了这些铅笔不一样长,你快去搞定它!不然就买化妆套给我!".
还好,这些铅笔的长度都是整数,蛤玮灵机一动,可以把些铅笔掰断使得它们可以一样长,当然要保证铅笔尽可能的长。 那么当这些铅笔最终一样长的时候,一共有多少支铅笔?

Input


T(1<=T<=100),表示数据组数.
每组数据第一行一个整数n(1<=n<=100),表示蛤玮买来的铅笔个数,接下来一行n个整数,表示n个铅笔的长度.保证长度都为正整数且小于1e7.
Output

每组数据输出一行,表示最终的铅笔个数.

Sample Input

2
2
2 3
3
4 6 14
Sample Output

5
12
HINT


对于第一个输入,最终掰成了5个长度为1的铅笔,第二个输入,最终掰成了12个长度为2的铅笔。


就是求n个数的最大公约数。如果是一个人的话就直接输出1,如果是多个人的话就是铅笔总长度除以n个铅笔长度的最大公约数
如下代码:

#include<iostream>
#include<cstdio>
using namespace std;

int GCD(int x, int y)
{ int t;
     while(y > 0) {
	 	t = x % y;
	 	x = y;
	 	y = t;
	 }
    return x;
}

int main(){
	int t;
	int a[105];
	int n;
	scanf("%d", &n);
	while(n--)
	while(scanf("%d",&t)==1){
		int s=0,gcd;
		for(int i=0; i<t; ++i){
			scanf("%d", &a[i]);
			s+=a[i];
		}
		if(t==1)
			printf("%d\n", t);
		else{
			gcd=GCD(a[0],a[1]);
			for(int i=2; i<t; ++i){
				gcd=GCD(gcd, a[i]);
			}
			printf("%d\n",s/gcd);
		}
		
	}
return 0;
}




Description

蛤玮成为了实验室主任,现在学校要求他建好一个机房里的通信网络.这个网络中有n台主机,现在已知建设好了m条线路,可以让一些主机直接或间接通信,为了使这n台主机互相之间都可以直接或间接通信,请问蛤玮最少还需建设多少条线路。
间接通信指:若A,B可以直接通信,B,C可以直接通信,则A,C可以间接通信,同理若C,D可以直接通信,A,D也可以间接通信。
Input

输入第一行为一个整数T(1<=T<=10),代表数据组数。对于每组数据,第一行为两个整数n(1<=n<=100),m(1<=m<=n*n),接下来m行每行两个整数u,v(1<=u,v<=n),表示主机u,v之间已建立线路。
Output

对于每组数据,输出一个整数,表示还需建设的线路数。
Sample Input

13 31 12 11 2
Sample Output

1






用并查集做,记录合并完之后还剩几个没有合并的路线然后减一就好了。
如下代码:

#include<iostream>
#include<cstdio>
#include<cstring>
#define M 1000+5
using namespace std;

int root[M],sz[M];
int count;

int find(int p){
	while(p!=root[p]){
		root[p]=root[root[p]];/*路径压缩,会破坏掉当前节点的父节点的尺寸信息,因为压缩后,当前节点的父节点已经变了 */ 
		p=root[p];
	}
	return p;
}

void merge(int p, int q){
	int pRoot=find(p);
	int qRoot=find(q);
	if(pRoot == qRoot )	return ;
	if(sz[pRoot]<sz[qRoot]){// 按秩进行合并,将子树小的挂在子树大的上边 
		root[pRoot]=qRoot;
		sz[qRoot]+=sz[pRoot];
		
	}else{
		root[qRoot]=pRoot;
		sz[pRoot]+=sz[qRoot];
	}
	--count; // 每次合并之后,树的数量减1
}

int main(){
	int t;
	scanf("%d",&t);
	while(t--){
		int n;
		scanf("%d%d", &count, &n);
		for(int i=1; i<=count; ++i){
			root[i]=i;
			sz[i]=1;
		}
		for(int i=0; i<n; ++i){
			int a,b;
			scanf("%d%d", &a, &b);
			merge(a, b);
		}
		printf("%d\n",count-1);
	}
	return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值