Bootstrap

2017北邮网安机试(回忆版)Problem A

Problem A

输入

先输入需要判断的组数T,然后依次两个字符串,共T组,字符串长度在20位以内

输出

每组字符串内不相同的字符的最大位数是多少

输入
3
baccc
abe
a
a
a
b
输出
5
0
1

说实话,没读懂题目啥意思,只能按照给出的用例来自我理解着写。。不知道对不对

#include<bits/stdc++.h>
#include<stdio.h>
int main(){
    int T;
    scanf("%d",&T);
    while(T--){
        char a[20];
        char b[20];
        scanf("%s%s",&a,&b);
        int l1=strlen(a);
        int l2=strlen(b);
        int num=0;
        if(l1>=l2){
            for(int i=0;i<l2;i++){
                if(a[i]!=b[i])
                    num++;
            }
            num+=l1-l2;
        }
        else{
            for(int i=0;i<l1;i++){
                if(a[i]!=b[i])
                    num++;
            }
            num+=l2-l1;
        }
        printf("%d\n",num);
    }
    return 0;
}

Problem B

B题 数独
输入
按照惯例,先输入组数T
然后输入T组的数据。为99的数组,要求满足:
1.每一行的数字不重复
2.每一列的数字不重复
3.每一宫的数字不重复
(每一宫即为将9
9数组划分为九个3*3块后,每块数据中九个数字不重复)
输出:
对每组数据,满足则输出Yes,否则输出No

输入:
1 2 3 4 5 6 7 8 9
2 3 4 5 6 7 8 9 1
3 4 5 6 7 8 9 1 2
4 5 6 7 8 9 1 2 3
5 6 7 8 9 1 2 3 4
6 7 8 9 1 2 3 4 5
7 8 9 1 2 3 4 5 6
8 9 1 2 3 4 5 6 7
9 1 2 3 4 5 6 7 8
输出:
NO
输入:
2 1 7 6 3 5 8 9 4
9 4 8 2 1 7 6 3 5
3 5 6 9 4 8 2 1 7
1 7 2 3 5 6 9 4 8
4 8 9 1 7 2 3 5 6
5 6 3 4 8 9 1 7 2
7 2 1 5 6 3 4 8 9
8 9 4 7 2 1 5 6 3
6 3 5 8 9 4 7 2 1
输出:
YES

一开始为了检查九宫格套了4层循环。。。结果有问题。。吃了没有文化的亏,没玩过数独,以为数字是随便填,可正可负可大可小。。后来度娘了下,,直接用hash来写。。。

#include<stdio.h>
#include<bits/stdc++.h>
using namespace std;
int judge(int a[10][10]){
    int flag=1;
    for(int i=1;i<=9;i++){
        for(int j=1;j<=9;j++)
            for(int k=1;k<=9;k++){
                if(j==k)
                    continue;
                else{
                    if(a[i][j]==a[i][k]){
                        flag=0;
                        break;
                    }
                    if(a[j][i]==a[k][i]){
                        flag=0;
                        break;
                    }
                }
        }
    }
    return flag;
}
int judge2(int a[10][10],int x,int y){
    int hash[10];
    int flag=1;
    for(int i=0;i<=9;i++)
        hash[i]=0;
    for(int i=0;i<3;i++){
        if(flag==0)
            break;
        for(int j=0;j<3;j++)
        {
            if(hash[a[x+i][y+j]]!=0){
                flag=0;
                break;
            }
            else
                hash[a[x+i][y+j]]=1;
        }
    }
    return flag;
}
int judge3(int a[10][10]){
    int flag=1;
    for(int i=0;i<3;i++){
        if(flag==0){
            break;
        }
        for(int j=0;j<3;j++){
            int nx=i*3+1;
            int ny=j*3+1;
            int flag2=judge2(a,nx,ny);
            if(flag2==0){
                flag=0;
                break;
            }
        }
    }
    return flag;
}
int main(){
    int buf[10][10];
    for(int i=1;i<=9;i++){
        for(int j=1;j<=9;j++){
            scanf("%d",&buf[i][j]);
        }
    }
    int flag=judge(buf);
    if(flag==0)
        printf("NO\n");
    else{
        int flag2=judge3(buf);
        if(flag2==0)
            printf("NO\n");
        else
            printf("YES\n");
    }
    return 0;
}

Problem C

C题 单词纠正
输入

一个句子,首字母需要大写,中间单词的字母都需要用小写。但i和bupt不管在哪里都需要大写。
输出
输出纠正后的句子

样例输入
i loVe bupt
hEllO wORlD
样例输出
I love BUPT
Hello world

废了好久时间,一直不知道问题在哪,所有的len都很小,查了下发现scanf在读取字符串时认为空格和回车都是结束。。。。僵硬。。。。改成gets就好了

#include<stdio.h>
#include<string.h>
using namespace std;
int main(){
        char str[40];
        gets(str);
        int len=strlen(str);
        char a[4]={'b','u','p','t'};
        char b[4]={'B','U','P','T'};
        for(int i=0;i<len;i++){
             if(str[i]==' ')
                continue;
             if(i==0){
                if(str[i]<='z'&&str[i]>='a')
                    str[i]-=32;
               }
             else{
             if(str[i]<='Z'&&str[i]>='A'){
                    str[i]+=32;
               }
           }
        }
        for(int i=0;i<len;i++){
            if(str[i]=='b'||str[i]=='B'){
                int flag=1;
                for(int j=0;j<4;j++){
                    if(str[i+j]!=a[j]&&str[i+j]!=b[j]){
                        flag=0;
                        break;
                    }
                }
                if(flag==1){
                    for(int j=0;j<4;j++){
                        str[i+j]=b[j];
                    }
                }
                i+=4;
            }
            if(str[i]=='i'){
                if(i==0)
                    continue;
                else if(i==len-1){
                    if(str[i-1]==' ')
                        str[i]='I';
                }
                else if(str[i-1]==' '&&str[i+1]==' ')
                    str[i]='I';
            }
        }
        for(int i=0;i<len;i++)
            printf("%c",str[i]);
}

后来写了个第二版,感觉逻辑更清晰:
#include<stdio.h>
#include<bits/stdc++.h>
using namespace std;
int main(){
    int T;
    scanf("%d",&T);
    getchar();
    while(T--){
        char str[50];
        gets(str);
        int len=strlen(str);
        for(int i=0;i<len;i++){
            if(i==0&&str[i]>='a'&&str[i]<='z')
                str[i]-=32;
            else{
                if(str[i]>='A'&&str[i]<='Z')
                    str[i]+=32;
            }
        }
        for(int i=0;i<len;i++){
            if(i!=0&&i!=len-1){
                if(str[i]=='i'&&str[i-1]==' '&&str[i+1]==' ')
                    str[i]-=32;
            }
            if(str[i]=='B'||str[i]=='b'){
                if(i<=len-4&&str[i+1]=='u'&&str[i+2]=='p'&&str[i+3]=='t'){
                    if(str[i]=='b')
                        str[i]-=32;
                    str[i+1]-=32;
                    str[i+2]-=32;
                    str[i+3]-=32;
                    i+=4;
                }
            }
        }
        puts(str);
    }
    return 0;
}

第四题没找到题目。。。但听大佬们说就是一个floyd跑下就好。。我把floyd的算法放在下面了。。。

伪代码:
ans[k][i][j]表示从i节点到j节点允许经过编号小于等于k的节点时其最短路径长度
for(int k=1;k<=n;k++){
	for(int i=1;i<=n;i++){
		for(int j=1;j<=n;j++){
			if(ans[i][k]==NULL||ans[k][j]==NULL) continue;
			if(ans[i][j]==NULL||ans[i][k]+ans[k][j]<ans[i][j])
				ans[i][j]=ans[i][k]+ans[k][j];
				}
```}
}

;