CSP-J第二轮试题-2021年-3题

2023-10-17 17:09:10 浏览数 (1)

参考:

https://www.luogu.com.cn/problem/P7911

总结

本系列为CSP-J/S算法竞赛真题讲解,会按照年份分析每年的真题,并给出对应的答案。本文为2021年真题。 https://www.luogu.com.cn/problem/list?tag=343&page=1

[CSP-J 2021] 网络连接

题目描述

TCP/IP 协议是网络通信领域的一项重要协议。今天你的任务,就是尝试利用这个协议,还原一个简化后的网络连接场景。

在本问题中,计算机分为两大类:服务机(Server)和客户机(Client)。服务机负责建立连接,客户机负责加入连接。

需要进行网络连接的计算机共有

n

台,编号为

1 sim n

,这些机器将按编号递增的顺序,依次发起一条建立连接或加入连接的操作。

每台机器在尝试建立或加入连接时需要提供一个地址串。服务机提供的地址串表示它尝试建立连接的地址,客户机提供的地址串表示它尝试加入连接的地址。

一个符合规范的地址串应当具有以下特征:

  1. 必须形如 a.b.c.d:e 的格式,其中
a, b, c, d, e

均为非负整数;

0 le a, b, c, d le 255

0 le e le 65535

a, b, c, d, e

均不能含有多余的前导

0

相应地,不符合规范的地址串可能具有以下特征:

  1. 不是形如 a.b.c.d:e 格式的字符串,例如含有多于
3

个字符 . 或多于

1

个字符 : 等情况;

  1. 整数
a, b, c, d, e

中某一个或多个超出上述范围;

  1. 整数
a, b, c, d, e

中某一个或多个含有多余的前导

0

例如,地址串 192.168.0.255:80 是符合规范的,但 192.168.0.999:80192.168.00.1:10192.168.0.1:088192:168:0:1.233 均是不符合规范的。

如果服务机或客户机在发起操作时提供的地址串不符合规范,这条操作将被直接忽略。

在本问题中,我们假定凡是符合上述规范的地址串均可参与正常的连接,你无需考虑每个地址串的实际意义。

由于网络阻塞等原因,不允许两台服务机使用相同的地址串,如果此类现象发生,后一台尝试建立连接的服务机将会无法成功建立连接;除此之外,凡是提供符合规范的地址串的服务机均可成功建立连接。

如果某台提供符合规范的地址的客户机在尝试加入连接时,与先前某台已经成功建立连接的服务机提供的地址串相同,这台客户机就可以成功加入连接,并称其连接到这台服务机;如果找不到这样的服务机,则认为这台客户机无法成功加入连接。

请注意,尽管不允许两台不同的服务机使用相同的地址串,但多台客户机使用同样的地址串,以及同一台服务机同时被多台客户机连接的情况是被允许的。

你的任务很简单:在给出每台计算机的类型以及地址串之后,判断这台计算机的连接情况。

输入格式

第一行,一个正整数

n

接下来

n

行,每行两个字符串

mathit{op}, mathit{ad}

,按照编号从小到大给出每台计算机的类型及地址串。

其中

mathit{op}

保证为字符串 ServerClient 之一,

mathit{ad}

为一个长度不超过

25

的,仅由数字、字符 . 和字符 : 组成的非空字符串。

每行的两个字符串之间用恰好一个空格分隔开,每行的末尾没有多余的空格。

输出格式

输出共

n

行,每行一个正整数或字符串表示第

i

台计算机的连接状态。其中:

如果第

i

台计算机为服务机,则:

  1. 如果其提供符合规范的地址串且成功建立连接,输出字符串 OK
  2. 如果其提供符合规范的地址串,但由于先前有相同地址串的服务机而无法成功建立连接,输出字符串 FAIL
  3. 如果其提供的地址串不是符合规范的地址串,输出字符串 ERR

如果第

i

台计算机为客户机,则:

  1. 如果其提供符合规范的地址串且成功加入连接,输出一个正整数表示这台客户机连接到的服务机的编号。
  2. 如果其提供符合规范的地址串,但无法成功加入连接时,输出字符串 FAIL
  3. 如果其提供的地址串不是符合规范的地址串,输出字符串 ERR

样例 #1

样例输入 #1
代码语言:javascript复制
5
Server 192.168.1.1:8080
Server 192.168.1.1:8080
Client 192.168.1.1:8080
Client 192.168.1.1:80
Client 192.168.1.1:99999
样例输出 #1
代码语言:javascript复制
OK
FAIL
1
FAIL
ERR

样例 #2

样例输入 #2
代码语言:javascript复制
10
Server 192.168.1.1:80
Client 192.168.1.1:80
Client 192.168.1.1:8080
Server 192.168.1.1:80
Server 192.168.1.1:8080
Server 192.168.1.999:0
Client 192.168.1.1.8080
Client 192.168.1.1:8080
Client 192.168.1.1:80
Client 192.168.1.999:0
样例输出 #2
代码语言:javascript复制
OK
1
FAIL
FAIL
OK
ERR
ERR
5
1
ERR

样例 #3

样例输入 #3
代码语言:javascript复制
见附件中的 network/network3.in。
样例输出 #3
代码语言:javascript复制
见附件中的 network/network3.ans。

样例 #4

样例输入 #4
代码语言:javascript复制
见附件中的 network/network4.in。
样例输出 #4
代码语言:javascript复制
见附件中的 network/network4.ans。

提示

【样例解释 #1】

计算机

1

为服务机,提供符合规范的地址串 192.168.1.1:8080,成功建立连接;

计算机

2

为服务机,提供与计算机

1

相同的地址串,未能成功建立连接;

计算机

3

为客户机,提供符合规范的地址串 192.168.1.1:8080,成功加入连接,并连接到服务机

1

计算机

4

为客户机,提供符合规范的地址串 192.168.1.1:80,找不到服务机与其连接;

计算机

5

为客户机,提供的地址串 192.168.1.1:99999 不符合规范。

【数据范围】

测试点编号

n ≤ n le n≤

特殊性质

1 1 1

10 10 10

性质 1 2 3

2 ∼ 3 2 sim 3 2∼3

100 100 100

性质 1 2 3

4 ∼ 5 4 sim 5 4∼5

1000 1000 1000

性质 1 2 3

6 ∼ 8 6 sim 8 6∼8

1000 1000 1000

性质 1 2

9 ∼ 11 9 sim 11 9∼11

1000 1000 1000

性质 1

12 ∼ 13 12 sim 13 12∼13

1000 1000 1000

性质 2

14 ∼ 15 14 sim 15 14∼15

1000 1000 1000

性质 4

16 ∼ 17 16 sim 17 16∼17

1000 1000 1000

性质 5

18 ∼ 20 18 sim 20 18∼20

1000 1000 1000

无特殊性质

n le

特殊性质

1
10

性质 1 2 3

2 sim 3
100

性质 1 2 3

4 sim 5
1000

性质 1 2 3

6 sim 8
1000

性质 1 2

9 sim 11
1000

性质 1

12 sim 13
1000

性质 2

14 sim 15
1000

性质 4

16 sim 17
1000

性质 5

18 sim 20
1000

无特殊性质

“性质 1”为:保证所有的地址串均符合规范; “性质 2”为:保证对于任意两台不同的计算机,如果它们同为服务机或者同为客户机,则它们提供的地址串一定不同; “性质 3”为:保证任意一台服务机的编号都小于所有的客户机; “性质 4”为:保证所有的地址串均形如 a.b.c.d:e 的格式,其中

a, b, c, d, e

均为不超过

{10}^9

且不含有多余前导

0

的非负整数; “性质 5”为:保证所有的地址串均形如 a.b.c.d:e 的格式,其中

a, b, c, d, e

均为只含有数字的非空字符串。

对于

100 %

的数据,保证

1 le n le 1000

【提供 hack 数据感谢】

  • xyf007。

答案1

代码语言:javascript复制
#include <bits/stdc  .h>
//#include<cstdio>//必须包含cstdio头文件
//#include<iostream>
using namespace std;


int n;
bool check(string ip){

    return true;
}
map<string,int> server;

int main(){
	//freopen("candy.in","r",stdin);
	//freopen("candy.out","w",stdout);
    cin>>n;
    string s,t;
    for(int i=1;i<=n;i  ){
        cin>>s>>t;
        if(!check(t)){ //检查ip地址是否合法
                cout<<"ERR"<<endl;
                continue;
        }
        if(s =="Server"){
                if(server[t]==0){
                    server[t]=i;
                    cout <<"OK"<<endl;
                }else{
                    cout<<"FAIL"<<endl;
                }
        }else{
            if(server[t]>0){
                cout<<server[t]<<endl;
            }else{
                cout<<"FAIL"<<endl;
            }
        }
    }

//    system("pause");
	//fclose(stdin);
	//fclose(stdout);


	return 0;
}
代码语言:javascript复制
#include <bits/stdc  .h>
//#include<cstdio>//必须包含cstdio头文件
//#include<iostream>
using namespace std;

struct node{
    int id;
    string sorc;
    string ip;
}a[1010];

bool check(string ip){

    return true;
}

int n;
int main(){


	//freopen("candy.in","r",stdin);
	//freopen("candy.out","w",stdout);
	// 接收一个n n为ip的数量
	cin>>n;


	// 循环
	for(int i=1;i<=n;i  ){
        // 接收 op(Server or Client)  ad(adress)
        string op,ad;
        cin>>op>>ad;
        // 判断ip 错误输出ERR
        if(!check(ad)){
            cout<<"ERR"<<endl;
        }

        // 判断数组为空 server直接进入OK,Client直接错FAIL
        if(i==1){
            if(op=="Server"){
                a[i].id=i;
                a[i].sorc="Server";
                a[i].ip=ad;
                cout<<"OK"<<endl;
                continue;
            }else{
                cout<<"FAIL"<<endl;
                continue;
            }
        }
        //int l = sizeof(a)/sizeof(a[0]);


        for(int j=1;j<=n;j  ){
            if(op=="Server"){
                if(a[j].sorc=="Server"){
                    if(ad==a[j].ip){

                        cout<<"FAIL"<<endl;
                        break;
                    }
                }else if(j==n){
                    a[i].id=i;
                    a[i].sorc="Server";
                    a[i].ip=ad;
                    cout<<"OK"<<endl;
                }

            }else{
                if(a[j].sorc=="Server"){
                    if(ad==a[j].ip){
                        cout<<a[j].id<<endl;
                        break;
                    }
                }else if(j==n){
                    cout<<"FAIL"<<endl;
                }
            }
        }
	}
    //system("pause");
	//fclose(stdin);
	//fclose(stdout);


	return 0;
}

答案2

代码语言:javascript复制
#include <bits/stdc  .h>
//#include<cstdio>//必须包含cstdio头文件
//#include<iostream>
using namespace std;


int n;
bool check(string ip){
    int t[6] = {0,-1,-1,-1,-1,-1};
    int cnt=sscanf(ip.c_str(),"%d.%d.%d.%d:%d",
                   &t[1],&t[2],&t[3],&t[4],&t[5]);
    if(cnt!=5) return false;
    for(int i=1;i<=4;i  ){
        if(t[i]<0||t[i]>255) return false;
    }
    if(t[5]<0 || t[5]>65535) return false;
    char now[30];
    sprintf(now,"%d.%d.%d.%d:%d",t[1],t[2],t[3],t[4],t[5]);
    if(string(now) !=ip) return false;
    return true;
}
map<string,int> server;

int main(){
	//freopen("candy.in","r",stdin);
	//freopen("candy.out","w",stdout);
    cin>>n;
    string s,t;
    for(int i=1;i<=n;i  ){
        cin>>s>>t;
        if(!check(t)){ //检查ip地址是否合法
                cout<<"ERR"<<endl;
                continue;
        }
        if(s =="Server"){
                if(server[t]==0){
                    server[t]=i;
                    cout <<"OK"<<endl;
                }else{
                    cout<<"FAIL"<<endl;
                }
        }else{
            if(server[t]>0){
                cout<<server[t]<<endl;
            }else{
                cout<<"FAIL"<<endl;
            }
        }
    }

//    system("pause");
	//fclose(stdin);
	//fclose(stdout);


	return 0;
}

现场真题注意事项

https://cspoj.com/contest.php?cid=1002 Fus5yz4x3EcSJH1Z

注意事项

  1. 文件名(程序名和输入输出文件名)必须使用英文小写。(提交必须使用freopen()进行提交)
  2. C/C 中函数 main() 的返回值类型必须是 int,程序正常结束时的返回值必须是0。
  3. 提交的程序代码文件的放置位置请参考各省的具体要求。
  4. 因违反以上三点而出现的错误或问题,申述时一律不予受理。
  5. 若无特殊说明,结果的比较方式为全文比较(过滤行末空格及文末回车)。
  6. 程序可使用的栈空间内存限制与题目的内存限制一致。
  7. 全国统一评测时采用的机器配置为:Inter® Core™ i7-8700K CPU @3.70GHz,内存 32GB。上述时限以此配置为准。
  8. 只提供 Linux 格式附加样例文件。
  9. 评测在当前最新公布的 NOI Linux 下进行,各语言的编译器版本以此为准

/* 假设输入样例数据存在文件test.in中,输出样例数据存在文件test.out中, 则在CSP、NOI等比赛的代码中,需添加freopen、fclose语句, 内容详见模板代码如下。 */

代码语言:javascript复制
#include <bits/stdc  .h>
#include<cstdio>//必须包含cstdio头文件
#include<iostream>
using namespace std;
 
int main(){
	freopen("test.in","r",stdin);
	freopen("test.out","w",stdout);
	
	cout<<"Hello NOI"<<endl;
	
	fclose(stdin);
	fclose(stdout);
	
	return 0;
}

下面为函数的简介,详细可参见 http://www.cplusplus.com/reference/clibrary/cstdio/freopen.html 函数名:freopen 声明:FILE *freopen( const char *path, const char *mode, FILE *stream ); 所在文件: stdio.h 参数说明: path: 文件名,用于存储输入输出的自定义文件名。 mode: 文件打开的模式。和fopen中的模式(如r-只读, w-写)相同。 stream: 一个文件,通常使用标准流文件。 返回值:成功,则返回一个path所指定文件的指针;失败,返回NULL。(一般可以不使用它的返回值) 功能:实现重定向,把预定义的标准流文件定向到由path指定的文件中。标准流文件具体是指stdin、stdout和stderr。其中stdin是标准输入流,默认为键盘;stdout是标准输出流,默认为屏幕;stderr是标准错误流,一般把屏幕设为默认。通过调用freopen,就可以修改标准流文件的默认值,实现重定向。

代码语言:javascript复制
#include<iostream>
#include<cstdio>
using namespace std;
int main(){
    freopen("7532.in", "r", stdin);
    freopen("7532.out", "w", stdout);
    //原来的代码保持不变
    double a, b, r;
    int k;
    cin >> a >> b;
    k = int(a/b);
    r = a - b * k;
    printf("%g", r);
    //-------------
    fclose(stdin);
    fclose(stdout);
    return 0;
}

0 人点赞