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;
}