九度OJ&北京航空航天大学2008机试题题解

题目一、jobdu1163:素数

http://ac.jobdu.com/problem.php?pid=1163

题目描述:

输入一个整数n(2<=n<=10000),要求输出所有从1到这个整数之间(不包括1和这个整数)个位为1的素数,如果没有则输出-1。

输入:

输入有多组数据。
每组一行,输入n。

输出:

输出所有从1到这个整数之间(不包括1和这个整数)个位为1的素数(素数之间用空格隔开,最后一个素数后面没有空格),如果没有则输出-1。

样例输入:
100
样例输出:
11 31 41 61 71
题目分析:

打表输出。


AC代码:


<span style="font-size:18px;">/**
 *快速求出素数,输出时判断个位是否是1
 */
#include<iostream>
using namespace std;
int a[10005]={0};
int main()
{
    for(int i=2;i<=10000;i++){
        if(a[i]==0) for(int j=i*i;j<=10000;j+=i){
            a[j]=1;
        }
    }
    int n;
    while(cin>>n){
        int ok=0,k=1;
        for(int i=1;i<n;i++){
            if(i!=1&&a[i]==0&&i%10==1){
                ok=1;//1~n之间存在满足条件的素数
                if(k) {cout<<i; k=0;}//控制空格
                else cout<<" "<<i;
            }
        }
        if(ok==0) cout<<"-1";
        cout<<endl;
    }
    return 0;
}
</span>

题目二、jobdu1164:旋转矩阵

http://ac.jobdu.com/problem.php?pid=1164

题目描述:

任意输入两个9阶以下矩阵,要求判断第二个是否是第一个的旋转矩阵,如果是,输出旋转角度(0、90、180、270),如果不是,输出-1。
要求先输入矩阵阶数,然后输入两个矩阵,每行两个数之间可以用任意个空格分隔。行之间用回车分隔,两个矩阵间用任意的回车分隔。

输入:

输入有多组数据。
每组数据第一行输入n(1<=n<=9),从第二行开始输入两个n阶矩阵。

输出:

判断第二个是否是第一个的旋转矩阵,如果是,输出旋转角度(0、90、180、270),如果不是,输出-1。

如果旋转角度的结果有多个,则输出最小的那个。

样例输入:
3
1 2 3
4 5 6
7 8 9
7 4 1
8 5 2
9 6 3
样例输出:
90
题目分析:

每次旋转进行比较,成功则输出,继续下次输入。旋转的时候,注意下标的关系。


AC代码:

<span style="font-size:18px;">/**
  *@xiaoran
  *模拟,分析下标之间的关系,当然要是有时间也可以直接模拟旋转
  *旋转90度后,a[i][j]=a[j][n-1-i];旋转180度相当于旋转90两次
  */
#include<iostream>
#include<cstdio>
#include<map>
#include<cstring>
#include<string>
#include<algorithm>
#include<queue>
#include<vector>
#include<stack>
#include<cstdlib>
#include<cctype>
#include<cmath>
#define LL long long
using namespace std;
int a[10][10];
int c[10][10];
void Zhuan(int n){
    int b[10][10];
    for(int i=0;i<n;i++){
        for(int j=0;j<n;j++){
            b[j][n-i-1]=a[i][j];
        }
    }
    memcpy(a,b,sizeof(b));//b数组赋值到a中
}
int Judge(int n){
    for(int i=0;i<n;i++){
        for(int j=0;j<n;j++){
            if(c[i][j]!=a[i][j]) return 0;
        }
    }
    return 1;
}

int main()
{
    int n;
    while(cin>>n){
        for(int i=0;i<n;i++){
            for(int j=0;j<n;j++){
                cin>>a[i][j];
            }
        }
        for(int i=0;i<n;i++){
            for(int j=0;j<n;j++){
                cin>>c[i][j];
            }
        }
        if(Judge(n)){
            cout<<"0"<<endl;
            continue;
        }
        Zhuan(n);
        if(Judge(n)){
            cout<<"90"<<endl;continue;
        }
        Zhuan(n);
        if(Judge(n)){
            cout<<"180"<<endl;continue;
        }
        Zhuan(n);
        if(Judge(n)){
            cout<<"270"<<endl;continue;
        }
        cout<<"-1"<<endl;
    }
    return 0;
}
</span>

题目三、jobdu1165:字符串匹配

http://ac.jobdu.com/problem.php?pid=1165

题目描述:

    读入数据string[ ],然后读入一个短字符串。要求查找string[ ]中和短字符串的所有匹配,输出行号、匹配字符串。匹配时不区分大小写,并且可以有一个用中括号表示的模式匹配。如“aa[123]bb”,就是说aa1bb、aa2bb、aa3bb都算匹配。

输入:

输入有多组数据。
每组数据第一行输入n(1<=n<=1000),从第二行开始输入n个字符串(不含空格),接下来输入一个匹配字符串。

输出:

输出匹配到的字符串的行号和该字符串(匹配时不区分大小写)。

样例输入:
4
Aab
a2B
ab
ABB
a[a2b]b
样例输出:
1 Aab
2 a2B
4 ABB
题目分析:

分段模拟,同时从前到后和从后到前进行比较,遇到’[‘和‘]’的时候,在进行特判是否成功。感觉北航的字符串提多的而且不区分大小写,大家注意了。


AC代码:

<span style="font-size:18px;">#include<iostream>
#include<string>
#include<algorithm>
#include<cctype>
using namespace std;
string s[1005],ss[1005];
int main()
{
    int n;
    while(cin>>n){
        string s1;
        for(int i=0;i<n;i++){
            cin>>s[i];
            ss[i]=s[i];
            for(int j=0;j<s[i].size();j++){
                if(isalpha(s[i][j])) s[i][j]=tolower(s[i][j]);
            }
        }
        cin>>s1;
        int k=1,ok=0;
        for(int i=0;i<s1.size();i++){//得到模式串的长度,不包含中括号里的字符
            if(s1[i]=='[') ok=1;
            else if(s1[i]==']') ok=0;
            else if(ok==0) k++;
        }
        //cout<<k<<endl;
        int k1,k2,ok1,ok2,j1,j2;
        for(int i=0;i<n;i++){
            if(s[i].size()!=k) continue;
            k2=s[i].size()-1;//前后同时匹配
            j1=0,j2=s1.size()-1;//前后同时匹配
            ok=ok1=ok2=1;
            while(ok1||ok2){//没有遇到前后括号
                /**
                cout<<s[i][j1]<<" "<<s1[j1]<<endl;
                cout<<s[i][k2]<<" "<<s1[j2]<<endl;
                **/
                if(s1[j1]=='[') ok1=0;
                if(s1[j2]==']') ok2=0;
                if(s[i][j1]!=s1[j1]&&s1[j1]!='['){
                    ok=0;
                }else{
                    if(ok1) j1++;
                }
                if(s[i][k2]!=s1[j2]&&s1[j2]!=']'){
                    ok=0;
                }else{
                    if(ok2){k2--; j2--;}
                }

            }
            /**
            cout<<ok<<endl;
            cout<<j1<<" "<<j2<<endl;
            **/
            if(ok==1) for(int j=j1+1;j<j2;j++){
                if(s[i][j1]==s1[j]){
                    cout<<i+1<<" "<<ss[i]<<endl;
                    break;
                }
            }
        }
    }
    return 0;
}
</span>


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值