每日一题03、04(养兔子、抄送列表、年会抽奖、收件人列表)

每日一题 专栏收录该内容
15 篇文章 0 订阅

1.上网的时候,访问某个网页却突然出现了某个运营商的网页(如联通、电信)。出现此问题可能的原因是?(A )

 A DNS劫持
 B DDoS攻击
 C MAC地址欺骗
 D 伪造DHCP服务器

NDS劫持:又称为域名劫持,是指在劫持的网络范围内拦截域名解析的请求,分析请求的域名,把审查范围以外的请求放行,负责返回假的IP地址或者什么都不做使请求失去响应,其效果就是对特定的网络不能反映或访问的是假网址。

DDos攻击:最基本的攻击就是利用合理的服务,请求来占用过多的服务资源,从而使合法用户无法得到服务的响应。

Mac地址欺骗:使局域网内主机无法访问局域网,通过修改交换机端口和Mac地址的映射。

2.TCP建立连接的三次握手中,第二次握手发送的包会包含的标记,最正确的描述是?(B)

 A ACK
 B SYN,ACK
 C SYN,PSH
 D SYN

3.当使用TCP协议编程时,下列问题哪个是必须由程序员考虑和处理的?(B)

 A 乱序数据包的重传
 B 数据传输过程中的纠错
 C 网络拥塞处理
 D 发送数据的格式和应用层协议

4.现在有很多网站都开始选择HTTPS作为默认的协议,HTTPS的用途是(C)

 A 可以加速页面的加载,提高响应速度
 B 可以让服务器端主动推送消息到客户端
 C 可以确保传输数据的安全性和防篡改
 D 为了提高浏览器兼容性

HTTPS中的S代表security(安全),HTTPS和HTTP的区别在于HTTPS的传输采用了加密方式,web服务器申请了证书并与服务器绑定,传输更安全

5.TCP断开连接的四次挥手中,第四次挥手发送的包会包含的标记,最正确的描述是?(C)

 A FIN
 B FIN,PSH
 C ACK
 D FIN,ACK 

TCP四次挥手:(由于TCP连接是全双工的,因此每个方向都必须单独进行关闭)

第一次:客户端发出释放FIN=1,自己序列号seq=u,进入FIN-WAIT-1状态;

第二次:服务器收到客户端后,发出ACK=1确认标志和客户端的确认号ack=u+1,自己的序列号seq=u,进入CLOSE-WAIT状态;

第三次:客户端收到服务器确认结果后,进入FIN-WAIT-2状态,此时服务器发送释放FIN=1信号,确认标志ACK=1,确认序号ack=u+1,自己序号 seq=w,服务器进入LAST-ACK(最后确认态)

第四次:客户端收到回复后,发送确认ACK=1,ack=w+1,自己的seq=u+1,客户端进入TIME-WAIT(时间等待),客户端经过2个最长报文段寿命后,客户端CLOSE;服务器收到确认后,立刻进入CLOSE状态。

6.某浏览器发出的HTTP 请求报文如下:

GET /index.html HTTP/1.1
Host: www.test.edu.cn
Connection: Close
Cookie: 123456
下列叙述中,错误的是(C)。

 A 该浏览器请求浏览 index.html
 B Index.html 存放在 www.test.edu.cn 上
 C 该浏览器请求使用持续连接
 D 该浏览器曾经浏览过 www.test.edu.cn

Connection:连接方式,close 表明为非持续连接方式。keep-alive表示持续连接方式
Cookie :值是由服务器产生的
HTTP请求报文中有Cookie 报头表示曾经访问过
www.test.edu.cn 服务器

7.主机甲和主机乙新建一个TCP 连接,甲的拥塞控制初始阈值为 32KB,甲向乙始终以 MSS=1KB 大小的段发送数据,并一直有数据发送;乙为该连接分配 16KB 接收缓存,并对每个数据段进行确认, 忽略段传输延迟。若乙收到的数据全部存入缓存,不被取走,则甲从连接建立成功时刻起,未发送超时的情况下,经过4个 RTT 后,甲的发送窗口是(A)。

 A 1KB
 B 8KB
 C 16KB
 D 32KB

发送窗口大小取决于min(rwnd,cwnd).
其中rwnd是接收缓存的空余大小,表示接收方还能接收多少。
cwnd就是我们常常画的慢增长曲线,拥塞避免曲线等等分析的纵轴数值。这里,其实很明确的告诉我们接收缓存只进不出,因此在不断减小。
cwnd从1MSS = 1KB开始,一个RTT后变为2KB,两个RTT后变为4KB,3RTT后变为8KB,4个RTT后变为16KB
同时呢,接收缓由16KB→15KB→13KB→9KB→1KB

8.通过POP3 协议接收邮件时,使用的传输层服务类型是(D)。TCP连接。

 A 无连接不可靠的数据传输服务
 B 无连接可靠的数据传输服务
 C 有连接不可靠的数据传输服务
 D 有链接可靠的数据传输服务

9.下列关于UDP协议的叙述中,正确的是 (B)
Ⅰ 提供无连接服务
Ⅱ 提供复用/分用服务
Ⅲ 通过差错校验,保障可靠数据传输

 A 仅Ⅰ
 B 仅Ⅰ、Ⅱ
 C 仅Ⅱ、Ⅲ
 D Ⅰ、Ⅱ、Ⅲ

10.主机甲与主机乙之间已建立一个TCP 连接,双方持续有数据传输,且数据无差错与丢失。若甲收到 1 个来自乙的 TCP 段,该段的序号为 1913、确认序号为 2046、有效载荷为 100 字节,则甲立即发送给乙的 TCP 段的序号和确认序号分别是(B )。

 A 2046、 2012
 B 2046、 2013
 C 2047、 2012
 D 2047、 2013

下一个TCP段的序号=上一个确认序号 ;下一个确认序号=上一个TCP段的序号+有效载荷。

序列号:4个字节,本报文段所发送的数据的第一个字节的序号。
确认序列号:4个字节,期望收到对方下一个报文段的第一个数据字节的序号。若确认号为N,说明到序号N-1为止的所有数据已经正确收到。
甲收到确认序号为 2046,说明乙期望收到的下一个报文段的第一个数据字节的序号为2046,到序号2046-1=2045为止的所有数据乙已经正确收到,所以甲立即发送给乙的 TCP 段的序号为2046。
甲收到的报文段的序号为 1913,有效载荷为 100 字节。报文段为1913到2012,甲期望期望收到的下一个报文段的第一个数据字节的序号为2013,因为甲已经收到了到2012为止的所有数据。

养兔子

题目描述

一只成熟的兔子每天能产下一胎兔子。每只小兔子的成熟期是一天。 某人领养了一只小兔子,请问第N天以后,他将会得到多少只兔子。

输入描述:

测试数据包括多组,每组一行,为整数n(1≤n≤90)。

输出描述:

对应输出第n天有几只兔子(假设没有兔子死亡现象)。

示例

输入
1
2
输出
1
2

其实就是一个斐波那契数列。 1 1 2 3 5 8 13…

代码
#include <iostream>
using namespace std;

int main(){
    int n;
    long a[100];
    a[1]=1;
    a[2]=2;
    while(cin>>n){
        for(int i=3;i<=n;i++){
            a[i]=a[i-1]+a[i-2];
        }
        cout<<a[n]<<endl;
    }
}

抄送列表

题目描述

NowCoder每天要处理许多邮件,但他并不是在收件人列表中,有时候只是被抄送。他认为这些抄送的邮件重要性比自己在收件人列表里的邮件低,因此他要过滤掉这些次要的邮件,优先处理重要的邮件。现在给你一串抄送列表,请你判断目标用户是否在抄送列表中。

输入描述:

输入有多组数据,每组数据有两行。第一行抄送列表,姓名之间用一个逗号隔开。如果姓名中包含空格或逗号,则姓名包含在双引号里。总长度不超过512个字符。第二行只包含一个姓名,是待查找的用户的名字(姓名要完全匹配)。长度不超过16个字符。

输出描述:

如果第二行的名字出现在收件人列表中,则输出“Ignore”,表示这封邮件不重要;否则,输出“Important!”,表示这封邮件需要被优先处理。

示例:

输入
Joe,Kewell,Leon
Joe
“Letendre, Bruce”,Joe,“Quan, William”
William
输出
Ignore
Important!

#include <iostream>
#include <vector>
#include <algorithm>//find函数

using namespace std;

int main()
{
	string line;
	while (getline(cin, line)) //第一次的输入抓到line里
	{
		vector<string> names; //names里存放所有的数据
		size_t pos = 0;
	
		while (pos < line.length())//位置如果大于等于了长度,那么证明找完了,双引号的情况从这里跳出
		{
			if (line[pos] == '\"') //找到双引号要处理双引号内部
			{
				size_t end = line.find("\"", pos + 1);
				names.push_back(line.substr(pos + 1, end - pos - 1));//截取出来放到names里
				//substr函数主要功能是复制子字符串,要求从指定位置开始,并具有指定的长度。第一个参数是子字符串的起始位置。第二个参数是复制的字符数目。
				pos = end + 2;//跳掉后面的双引号和逗号
			}
			else
			{
				size_t end = line.find(",", pos + 1);
				//找不到逗号证明这是最后一个字符串了,直接存了这个字符串后跳出
				if (end == -1)
				{
					names.push_back(line.substr(pos, line.size() - pos));
					break;
				}
				names.push_back(line.substr(pos, end - pos));
				pos = end + 1; //跳掉后面的逗号
			}
		}
		getline(cin, line);
		if (names.end() == find(names.begin(), names.end(), line))
			//find函数是在两个迭代器中间查找,前两个参数分别是起始位置和结束位置,最后一个参数是要找的值。
			//找到了返回对应迭代器,找不到就返回区间末尾的位置。本例中是end()。
		{
			printf("Important!\n"); //没找到
		}
		else
		{
			printf("Ignore\n"); //找到了
		}
	}
	return 0;
}

年会抽奖

题目描述

今年公司年会的奖品特别给力,但获奖的规矩却很奇葩:首先,所有人员都将一张写有自己名字的字条放入抽奖箱中; 待所有字条加入完毕,每人从箱中取一个字条; 如果抽到的字条上写的就是自己的名字,那么“恭喜你,中奖了!”现在告诉你参加晚会的人数,请你计算有多少概率会出现无人获奖?

输入描述:

输入包含多组数据,每组数据包含一个正整数n(2≤n≤20)

输出描述:

对应每一组数据,以“xx.xx%”的格式输出发生无人获奖的概率

示例:

输入 2
输出 50.00%

这是一道典型的错排算法,就是当有 n 个对象的时候,保证每一个对象都不在自己原来的位置上的方法有 D(N) 种,下面是它的通项:
在这里插入图片描述

#include <iostream>
#include <cstdio>

using namespace std;

int main(){
	long d[22] = { 0, 0, 1 };// 错排数量,第一项为0是为了配合下文中输入的n。1个对象时,方法0种。2个对象时,方法1种。
	long f[22] = { 0, 1, 2 };// 阶乘。1个对象时,阶乘为1。2个对象时,阶乘为2。 
	
	for (int i = 3; i < 22; i++){
		d[i] = (i - 1) * (d[i - 1] + d[i - 2]); // 错排的递推公式
		f[i] = i * f[i - 1]; // 阶乘的递推公式
	}

	int n;
	while (cin >> n){
		printf("%.2f%\n", 100.0 * d[n] / f[n]);
		// 用 100.0 来把结果处理成 double ,保留两位小数
	}

	system("pause");
	return 0;
}

收件人列表

题目描述

NowCoder每天要给许多客户写电子邮件。正如你所知,如果一封邮件中包含多个收件人,收件人姓名之间会用一个逗号和空格隔开;如果收件人姓名也包含空格或逗号,则姓名需要用双引号包含。
现在给你一组收件人姓名,请你帮他生成相应的收件人列表。

输入描述:

输入包含多组数据。
每组数据的第一行是一个整数n (1≤n≤128),表示后面有n个姓名。
紧接着n行,每一行包含一个收件人的姓名。姓名长度不超过16个字符。

输出描述:

对应每一组输入,输出一行收件人列表。

示例

输入:
3
Joe
Quan,William
Letendre,Bruce
2
Leon
Kewell
输出
Joe,“Quan,William”,“Letendre,Bruce”
Leon,Kewell

代码:
简洁版代码:

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

int main()
{
    int n;
    while(cin>>n)
    {
        getchar(); //刷新缓冲区
        while(n--)
        {
            string str;
            getline(cin, str);
            if(str.find(',')!= -1 || str.find(' ')!= -1)//遇到,和空格直接给字符串前后加"即可
            {
                str.insert(str.begin(), '"');
                str.insert(str.end(), '"');
            }
            if(n == 0)
                cout<<str<<endl;
            else
                cout<<str<<", ";
        }
    }
    return 0;
}
补充版代码,没有简版利于理解。

#include <iostream>
#include <string>
#include <cstdio>

using namespace std;

int main()
{
   int n;
   while(cin >> n) //接收数字
   {
     cin.get(); //处理回车
     string name;
     for(int i=0; i < n; i++) //名字分别处理
     {   
       bool quote = false;
       getline(cin, name);
       if (name.find(',') != std::string::npos ||
       name.find(' ') != std::string::npos) //找到逗号或者空格,就要加双引号
       //std::string::npos作为string的成员函数的一个长度参数时,表示“直到字符串结束”。
       {
         quote = true;
       }
       
       if (quote)
       {
         putchar('\"'); //putchar效率更高
       }
       
       cout << name;
       
       if (quote)
       {
         putchar('\"');
       }
       
       if (i == n - 1) //如果已经是最后一个字符串,那就补回车,否则加逗号和空格
       {
         putchar('\n');
       }
       else
       {
         putchar(',');
         putchar(' ');
       }
     }
   }
   return 0;
}
  • 0
    点赞
  • 0
    评论
  • 0
    收藏
  • 打赏
    打赏
  • 扫一扫,分享海报

©️2022 CSDN 皮肤主题:大白 设计师:CSDN官方博客 返回首页

打赏作者

你的鼓励将是我创作的最大动力

¥2 ¥4 ¥6 ¥10 ¥20
输入1-500的整数
余额支付 (余额:-- )
扫码支付
扫码支付:¥2
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值