帝国国王科技大学上机题解

来源:互联网 发布:世界第一社交网络 编辑:程序博客网 时间:2024/05/02 05:05

1.变位词问题(18分)

 

问题描述

所谓变位词,是指组成各个单词的字母完全相同,只是字母排列的顺序不同。例如:silentlisten就是一对变位词。给出两个字符串,要求判断其是否互为变位词,若是,返

回“Yes”,否则返回“No”。


Input

输入正整数N,表示N例测试。接着输入N组数据,每组数据一行,包含两个字符串。

Output

对每组输入数据,输出一行,“Yes”表示是变位词,“No”表示不是变位词。

 

Sample Input

2

silent listen

stop sort

Sample Output

Yes

No


解题思路:

利用map把两个字符串里的每个字符的个数统计到数组a和数组b中。如果完全相同,返回Yes,不同的话返回No。

PS:可能两个字符串中会包含!@#$%^&等字符。

代码:

#include<iostream>#include<cstdio>#include<vector>#include<algorithm>#include<cstring>#include<map>#define maxn 1005using namespace std;int a[1005];int b[1005];char str1[10005];char str2[10005];map <char,int> mq;int main(){    int n,i,len;    while(cin>>n)    {        while(n--)        {            int t=0;            mq.clear();            memset(a,0,sizeof(a));            memset(b,0,sizeof(b));            cin>>str1;            len=strlen(str1);            for(i=0; i<len; i++)            {                if(!mq[str1[i]])                {                    mq[str1[i]]=++t;                    a[t]++;                }                else                {                    a[mq[str1[i]]]++;                }            }            cin>>str2;            len=strlen(str2);            for(i=0; i<len; i++)            {                if(!mq[str2[i]])                {                    mq[str2[i]]=++t;                    b[t]++;                }                else                {                    b[mq[str2[i]]]++;                }            }            /*if(strcmp(str1,str2)==0)            {                cout<<"No"<<endl;                continue;            }*/            int flag=1;            for(i=0; i<1000; i++)            {                if(a[i]!=b[i])                {                    flag=0;                    break;                }            }            if(flag) cout<<"Yes"<<endl;            else cout<<"No"<<endl;        }    }    return 0;}/*4beijinguniversityofpostsandtelecommunicationsnnsemnoimfeiaugtyittouinjpdonssaiebcsiervctolschoolofcomputerscience  icooeeorhufmpcntepcslcscdmpnb.enuet.@ua    name@bupt.edu.cncongratulations   nncatrlsaoogucit*/


2.加密问题(16分)

 

问题描述

信息社会,密码与我们生活息息相关。为了安全起见,可通过简单加密机制把明文加密成密文。这里的加密机制是利用手机上的字母与数字键的对应关系:1--1abc--2def--3ghi--4jkl--5mno--6pqrs--7tuv--8wxyz--90--0。加密机制为:

1)密码中出现的小写字母都变成对应的数字;

2)密码中出现的大写字母都变成小写之后往后移一位,如果是大写字母Z,则后移一位变成a

3)数字和其他的符号都不做变换。

声明:密码中没有空格,可包含特殊字符,如~@#$等。

 

Input

输入正整数N,表示N例测试。接着输入N组数据,每组数据一行,包含一个明文字符串,长度不超过100

Output

对每组输入数据,输出一行对应的密文。

 

Sample Input

2

ZHANGsan&2016

Name@32#

Sample Output

Aiboh726&2016

O263@32#


代码:

PS:代码写的比较乱,用了很多if,else。。。

#include<iostream>#include<cstdio>#include<vector>#include<algorithm>#include<cstring>#define maxn 1005using namespace std;char str1[1005];int main(){    int n,i,len;    while(cin>>n)    {        while(n--)        {            cin>>str1;            len=strlen(str1);            for(i=0; i<len; i++)            {                if(str1[i]>='A'&&str1[i]<='Y')                {                    str1[i]=str1[i]-'A'+'a'+1;                }                else if(str1[i]=='Z')                {                    str1[i]='a';                }                else if(str1[i]>='a'&&str1[i]<='c')                {                    str1[i]='2';                }                else if(str1[i]>='d'&&str1[i]<='f')                {                    str1[i]='3';                }                else if(str1[i]>='g'&&str1[i]<='i')                {                    str1[i]='4';                }                else if(str1[i]>='j'&&str1[i]<='l')                {                    str1[i]='5';                }                else if(str1[i]>='m'&&str1[i]<='o')                {                    str1[i]='6';                }                else if(str1[i]>='p'&&str1[i]<='s')                {                    str1[i]='7';                }                else if(str1[i]>='t'&&str1[i]<='v')                {                    str1[i]='8';                }                else if(str1[i]>='w'&&str1[i]<='z')                {                    str1[i]='9';                }            }            cout<<str1<<endl;        }    }    return 0;}/*2School!Of@Computer#Science$NLP2016^BYR*bupt%BeiJing/China*/



3.求连续子数组最大和(20分)

 

问题描述

输入一个整形数组,数组里有正数也有负数。数组中连续的一个或多个整数组成一个子数组,每个子数组都有一个和。求所有子数组的和的最大值,并给出子数组的首末位置。

 

Input

输入正整数N,表示N例测试。接着输入N组数据,每组数据一行,包含一个数组。

Output

对每组输入数据,输出该数组对应的最大连续子数组和,子数组的首位置,末位置。

 

Sample Input

2

1 -2 3 10 -4 7 2 -5

1 -9 5 5

Sample Output

18 2 6

10 2 3


解题思路:

如果用a表示给定的初始数组,dp[i]表示以i为末位置的最大连续子数组的和,那么dp[i]=max(dp[i-1]+a[i],dp[i])


代码:

#include<iostream>#include<cstdio>#include<vector>#include<algorithm>#include<cstring>#define maxn 1005using namespace std;int a[1005];int dp[1005];char str[1005];int ma(int a,int b){    if(a>b) return a;    return b;}int main(){    int n,i,len,m;    while(cin>>n)    {        gets(str);        while(n--)        {            memset(dp,0,sizeof(dp));            m=0;            gets(str);            len=strlen(str);            int tmp=0,flag=0;            for(i=0; i<len; i++)   //将字符串处理成int数组保存在数组a中             {                if(str[i]=='-')                {                    flag=1;                }                else if(str[i]==' ')                {                    if(flag)                        a[m++]=0-tmp;                    else                        a[m++]=tmp;                    flag=0;                    tmp=0;                }                else                    tmp=tmp*10+(str[i]-'0');            }            if(flag)                a[m++]=0-tmp;            else                a[m++]=tmp;            flag=0;            tmp=0;            /*            cout<<m<<endl;            for(i=0;i<m;i++)                cout<<a[i]<<" ";            cout<<endl;            */            if(a[0]>=0) dp[0]=a[0];            else dp[0]=0;            for(i=1; i<m; i++)      //利用递推公式                 dp[i]=ma(a[i],dp[i-1]+a[i]);            int fla=0;    //处理没有正数的情况 ,特判             for(i=0; i<m; i++)            {                if(a[i]>0)                {                    fla=1;                }            }            if(fla==0)   //处理没有正数的情况 ,特判             {                int ss,ee,mm=-1000000000;                for(i=0; i<m; i++)                {                    if(a[i]>mm)                    {                        mm=i;                        ss=i;                        ee=i;                    }                }                cout<<mm<<" "<<ss<<" "<<ee<<endl;                continue;            }            int mm=-1000000000,e,s;            for(i=0; i<m; i++)   //找到dp的最大值             {                if(dp[i]>mm)                {                    mm=dp[i];                    e=i;                }            }            int pp=mm;            for(i=e; i>=0; i--)   //根据总和和末位置找到起始位置             {                pp-=a[i];                if(pp==0)                {                    s=i;                    break;                }            }            cout<<mm<<" "<<s<<" "<<e<<endl;        }    }    return 0;}/*1001 -2 3 10 -4 7 2 -51 -9 5 5-1 -1 -1-1 2 20 -1 -131 -2 3 10 -4 7 2 -5 -19 10 8 -3 -8 361 59 62 -107 22 23 -113 14 54 57 -76 -116 78 0 7 -70 50 -58 -94 1 53 38 55 65 16 48 32 8 27 8 -108 63 -50 14 69 -103 -112 -51 40 5396 30 163 37 65 -232 121 -295 15 119 11 177 -149 128 68 -217 -290 196 169 -32 -261 194 -85 48 -87 84 89 -152 -98 96 177 198 -144 154 -67 125 -224 -110 182 -155 72 43 92 -127 40 84 85 -285 171 69 157 176 -24 149 -98 59 188 58 193 145 -208 32 -9 182 -191 97 54 92 101 -79 -111 35 -28 -48 96 128 46 -193 -182 -111 45 170 182 136 147 79 12 53 11 -171 90 199 26 120 60 59 52 -111 -113 148*/


4.整数的最小平方分解(23分)

 

问题描述

给定一个正整数n,总能分解成若干个完全平方数的和(这里完全平方数为1491625...),请找出n的最小平方分解数,例如,n=12时,12=4+4+4,返回最小平方分解数3n=13时,13=4+9,返回最小平方分解数2

 

Input

输入正整数N,表示N例测试。接着输入N组数据,每组数据一行,包含一个正整数。

Output

对每组输入数据,输出其最小平方分解数。

 

Sample Input

4

12

13

2016

Sample Output

2

3

2

3


解题思路:

思路一,可以利用递归的思想dfs(cur,deep),寻找最优解。cur是当前的值,deep是当已经用的平方数的个数。 如果cur为0,那么把deep和结果比较,选小的。为了记忆化搜索,用vis数组保存cur的是否访问过,还有p数组,p[i]到达cur状态所用的最小步数。

1)如果cur没访问过,便访问。

2)如果cur访问过,并且当前到达的步数更少的话,也可以继续搜索。

代码:

#include<iostream>#include<cstdio>#include<cstring>#include<cmath>#define INF 0x7fffffff#define maxn 1000005using namespace std;int ans;int a[maxn];int m,n;int vis[maxn];int p[maxn];void dfs(int cur,int deep){    if(deep>10)        return;    if(cur==0)    {        if(deep<ans)        {            ans=deep;            return;        }    }    else if(cur<0)    {        return;    }    for(int i=sqrt(cur); i>=1; i--)    {        int t=cur/(i*i);        for(int j=1; j<=t; j++)        {            if(!vis[cur-j*i*i])            {                vis[cur-j*i*i]=1;                p[cur-j*i*i]=deep+j;                dfs(cur-j*i*i,deep+j);            }            if(vis[cur-j*i*i]&&p[cur-j*i*i]>deep+j)            {                vis[cur-j*i*i]=1;                p[cur-j*i*i]=deep+j;                dfs(cur-j*i*i,deep+j);            }        }    }}int main(){    while(cin>>n)    {        while(n--)        {            memset(vis,0,sizeof(vis));            memset(p,0,sizeof(p));             cin>>m;            ans=INF;            dfs(m,0);            cout<<ans<<endl;        }    }    return 0;}


思路二,这个题是典型的完全背包。

具体可以参加背包九讲问题。



当然这个题有些许不同,动态转移方程为dp[j]=min(dp[j-i*i]+1,dp[j]);

代码:

#include<iostream>#include<cstdio>#include<cstring>#include<cmath>#define INF 0x7fffffff#define maxn 400005using namespace std;int dp[maxn];void pre(){    int i,j;    for(i=1;i<maxn;i++)        dp[i]=INF;    dp[0]=0;    for(i=1;i<=1000;i++)    {        for(j=0;j<maxn;j++)        {            if(j>=i*i&&dp[j-i*i]!=INF)            {                dp[j]=min(dp[j-i*i]+1,dp[j]);            }        }    }}int main(){    pre();    int n,m;    while(cin>>n)    {        while(n--)        {            cin>>m;            cout<<dp[m]<<endl;        }    }    return 0;}



5.矩阵的ZigZag排列(23分)

 

问题描述

输入一个仅包含正整数n×n矩阵array,输出该矩阵的ZigZag排列,其中array[0][0]是排列的起点,array[n-1][n-1]是排列的终点。例如:输入一个4×4的矩阵


输出其ZigZag排列:1 2 5 9 6 3 4 7 10 13 14 11 8 12 15 16

 

Input

输入正整数N,表示N例测试。接着输入N组数据,每组数据为一个n×n的矩阵,即先输入n,然后输入n行数据。

Output

对每组输入数据,输出一行该矩阵的ZigZag排列。

 

Sample Input

2

2

1 2

3 4

4

1 2 3 4

5 6 7 8

9 10 11 12

13 14 15 16

Sample Output

1 2 3 4

1 2 5 9 6 3 7 10 13 14 11 8 12 15 16


解题思路:

其实这个题目只有四个方向,正右,左下,正下,右上。如果x,y表示当前坐标。这四个方向坐标变化依次为+{{0,1},{1,-1},{1,0},{-1,1}};

可以采用递归的思想,关键就是判断方向,什么时候改变方向,有几种可能。


代码:

#include<iostream>#include<cstdio>#define maxn 1005using namespace std;int a[maxn][maxn];int d[4][2]= {{0,1},{1,-1},{1,0},{-1,1}};int m;void dfs(int curx,int cury,int dir){    cout<<a[curx][cury]<<" ";    if(curx==m&&cury==m)        return;    curx=curx+d[dir][0];    cury=cury+d[dir][1];    if(dir==0)    {        if(curx==1)            dir=1;        else            dir=3;    }    else if(dir==1)    {        if(curx==m)            dir=0;        else if(cury==1)            dir=2;        else            dir=1;    }    else if(dir==2)    {        if(cury==1)            dir=3;        else            dir=1;    }    else    {        if(curx==1)            dir=0;        else if(cury==m)            dir=2;        else            dir=3;    }    dfs(curx,cury,dir);}int main(){    int n,i,j;    while(cin>>n)    {        while(n--)        {            cin>>m;            for(i=1; i<=m; i++)            {                for(j=1; j<=m; j++)                {                    cin>>a[i][j];                }            }            //cout<<"****"<<endl;            dfs(1,1,0);            cout<<endl;        }    }    return 0;}/*2826 -57 30 16 0 45 -16 -32-47 -53 18 0 38 -28 12 212 -49 9 41 53 -59 -7 -1451 21 1 27 38 -29 29 3760 26 36 -44 14 -12 -58 571 -2 23 32 30 -16 62 10-44 17 34 23 14 -36 46 3626 -3 0 40 7 -5 49 5116-226 247 6 -116 227 32 234 -42 -125 -36 153 71 -144 110 -66 -217-3 80 -65 6 -137 130 27 -124 244 -241 -28 197 -170 97 2 3045 -150 69 110 100 165 54 217 72 196 207 219 -72 159 93 107225 159 252 62 50 99 13 -92 236 14 -125 229 127 202 11 176219 -148 -7 163 90 -157 -98 83 -172 119 208 -183 151 149 230 207-17 79 -12 168 165 -108 130 -230 136 79 232 -200 191 180 111 3684 30 -5 252 -132 13 221 58 74 124 180 -90 76 150 -23 -23725 -147 120 108 -220 52 77 148 -216 14 45 35 110 173 188 185123 -50 112 167 52 -131 -29 10 -221 72 -220 -207 -73 9 -22 177-249 75 83 -79 202 27 -146 -3 195 126 163 210 75 159 31 -250-87 -43 105 -107 142 -219 207 -196 230 -225 -80 -79 -198 32 216 10159 63 155 -14 -33 -194 -88 156 86 104 146 163 157 14 108 -43184 231 166 224 81 126 205 159 241 -181 -224 -6 248 -1 170 115120 76 98 -58 -243 152 107 86 62 -215 43 165 27 -105 -81 16534 -248 125 115 2 226 21 -43 163 168 99 211 -1 -246 215 204-208 199 19 -120 15 146 -29 -13 166 89 148 -250 -66 104 40 -253*/



1 0
原创粉丝点击