练习8

问题 B: 弟弟的作业


时间限制: 1 Sec  内存限制: 128 MB



提交: 80  解决: 41  外部导入


提交状态讨论版 
  



题目描述 


你的弟弟刚做完了“100以内数的加减法”这部分的作业,请你帮他检查一下。每道题目(包括弟弟的答案)的格式为a+b=c或者a-b=c,其中a和b是作业中给出的,均为不超过100的非负整数;c是弟弟算出的答案,可能是不超过200的非负整数,也可能是单个字符"?",表示他不会算。 



输入 


输入文件包含不超过100行,以文件结束符结尾。每行包含一道题目,格式保证符合上述规定,且不包含任何空白字符。输入的所有整数均不含前导0。 



输出 


输出仅一行,包含一个非负整数,即弟弟答对的题目数量。 



样例输入 Copy 

1+2=3
3-1=5
6+7=?
99-0=99



样例输出 Copy 

2
int main()
 {
  char s[30];
  int a,b,c;
  int sum=0;
  while(scanf("%s",&s)!=EOF)
 
 {
    if(sscanf(s,"%d+%d=%d",&a,&b,&c)==3&&(a+b==c)) 
        sum++;
    if(sscanf(s,"%d-%d=%d",&a,&b,&c)==3&&(a-b==c)) 
        sum++;
  }
  cout<<sum<<endl;
return 0;
}

其实这个题目就只要判断“=”后面的数整部正确并且是不是“?”;如果是“?”的话就不管,不是的话再判断是不是正确的数,如果是正确的是,那么sum++;

另一种思路就是用atof()函数,在逆波兰表达式中提到过这个函数的一丢丢用法;

以文件结尾结束就是 crl+z会输出sum的答案

 

问题 C: 求解n阶螺旋矩阵问题


时间限制: 1 Sec  内存限制: 128 MB



提交: 0  解决: 0  201501010119


提交状态讨论版 
  



题目描述 

创建n阶螺旋矩阵并输出。 



输入 

输入包含多个测试用例,每个测试用例为一行,包含一个正整数n(1<=n<=50),以输入0表示结束。 



输出 

每个测试用例输出n行,每行包括n个整数,整数之间用一个空格分割。 



样例输入 Copy 

4
0



样例输出 Copy 

1 2 3 4
12 13 14 5
11 16 15 6
10 9 8 7
int a[55][55];


int main()
{
    int n,i,j,b;

    while(scanf("%d",&n)&&n)
    {
        int flag=1;
     for(b=0;b<=(n+1)/2;b++)
     {
         for(j=b;j<=n-b-1;j++)
         a[b][j]=flag++;
         
         for(i=b+1;i<n-b-1;i++)
         a[i][n-b-1]=flag++;
         
         for(j=n-b-1;j>b;j--)
         a[n-b-1][j]=flag++;
         
         for(i=n-b-1;i>b;i--)
         a[i][b]=flag++;
     }    

     for(i=0;i<n;i++)
     {
         for(j=0;j<n;j++)
        if(j==0)
            cout<<a[i][j];
        else
            cout<<" "<<a[i][j];
        cout<<endl;
      }  
    }
     return 0;
}     

 

问题 D: 最大子段和


时间限制: 1 Sec  内存限制: 128 MB



提交: 1  解决: 1  201501010119


提交状态讨论版 
  



题目描述 

给定n个整数(可能是负数)组成的序列a[1], a[2], a[3], …, a[n],求该序列的子段和如a[i]+a[i+1]+…+a[j]的最大值。 



输入 

每组输入包括两行,第一行为序列长度n,第二行为序列。    



输出 

输出字段和的最大值。 



样例输入 Copy 

5
-1 0 1 2 3




样例输出 Copy 

6
int a[1000];
int n;
int maxx(int a[],int n)
{
    int b,sum;   
    if(a[0]>0)
        b=a[0];   //判断第一个数是否为正,为正直接加,为负将b赋值为0;
    else
        b=0;
    sum=b;     //sum用来找b中的最大值(也就是找子段和中最大的子段和)
    for(int i=1;i<n;i++)  
    {
        if(b>0)   //如果b为正,就一直加(不管a[i]是否为负,只要b为正,都要一直加a[i])
            b=b+a[i];
        else   //直到b为负,那么就不管这个子段了,重新从a[i]开始算另一个子段和
            b=a[i];
        if(b>sum)   //取众多子段的最大的那个子段
            sum=b;
    }
    return sum;
}

int main()
{
    while(cin>>n)
    {
        int i;
        for(i=0;i<n;i++)
            cin>>a[i];
        cout<<maxx(a,n)<<endl;
    }
    return 0;
}

动态规划法;

b[i]表示以a[i]结尾的子段和;

判断b[i-1]是否为正,为正的话:b[i-1]+a[i]放在b[i]里;否则,就从下一个子段开始,并且判断每次加的子段的最大值,输出的是最大值sum。

 

问题 F: 牛牛的字符串


时间限制: 1 Sec  内存限制: 128 MB



提交: 1  解决: 1  201501010119


提交状态讨论版 
  



题目描述 


牛牛有两个字符串(可能包含空格),他想找出其中最长的公共连续子串的长度,希望你能帮助他。例如:两个字符串分别为"abede""abgde",结果为2。




输入 

每组数据包括两行,每行为一个字符串。 



输出 

输出最长的公共连续子串的长度。    



样例输入 Copy 

abede
abgde



样例输出 Copy 

2
int dp[1000][1000];
char a[1000],b[1000];
int maxx=0;
int lsc(int x,int y)
{
    int i,j;
    for(i=0;i<x;i++)
    {
        if(a[i]==b[0])
        dp[i][0]=1;
    }
    for(j=0;j<y;j++)
    {
        if(b[j]==a[0])
        dp[0][j]=1;
    }
    for(i=1;i<x;i++)
        for(j=1;j<y;j++)
        {
            if(a[i]==b[j])
                dp[i][j]=dp[i-1][j-1]+1;
            if(dp[i][j]>=maxx)
                maxx=dp[i][j];
        }
        return maxx;
}
int main()
{
   while(cin>>a)
   {
        cin>>b;
        int x=strlen(a);
        int y=strlen(b);
        cout<<lsc(x,y)<<endl;;
   }
    return 0;
}

 这个代码还是有点问题的,因为当输入的两个字符串某个长度为1的时候会输出0,所以我们在主函数中判断一下字符串长度是否为1,为1的话就直接线性查找;

最长公共子序列:要求相对位置一致就行;

dp[i][j]表示x从第一个到第i个,y从第一个到第j个;

 填表法:长的为行,短的为列,第一行第二行全0,若行列的两个字母相同,dp数组=左上角的dp数组+1,不相等的话取上面和前面的最大值;

最后取右下角

 

 

问题 G: 最长公共子序列问题(LCS)-构造LCS


时间限制: 1 Sec  内存限制: 128 MB



提交: 2  解决: 1  201501010119


提交状态讨论版 
  



题目描述 

使用动态规划算法求两个序列的最长公共子序列,需构造一条最长公共子序列。 



输入 

每组输入包括两行,每行包括一个字符串。    



输出 

两个字符序列的一条最长公共子序列。(输入已确保最长公共子序列的唯一性)    



样例输入 Copy 

acdbxx
ccdxx



样例输出 Copy 

cdxx
char a[1000],b[1000];
int aa[100][100];
int dp[100][100];
 
 void lcs(int i,int j)
 {
     if(i==0||j==0)  //找完了,结束递归
        return ;
     if(dp[i][j]==1)  //先回溯,再输出
     {
         lcs(i-1,j-1);
         cout<<a[i-1];
     }
     else if(dp[i][j]==2)
        lcs(i-1,j);
     else
        lcs(i,j-1);
 }
 
int main()
{
    memset(aa,0,sizeof(aa));
    while(cin>>a)
    {
        cin>>b;
        int m=strlen(a);
        int n=strlen(b);
         for(int i=1;i<=m;i++)
        for(int j=1;j<=n;j++)
        {
            if(a[i-1]==b[j-1])
                {
                    aa[i][j]=aa[i-1][j-1]+1;
                    dp[i][j]=1;
                }
            else
                {
                    if(aa[i-1][j]>aa[i][j-1])
                    {
                        aa[i][j]=aa[i-1][j];
                        dp[i][j]=2;
                    }
                    else
                    {
                        aa[i][j]=aa[i][j-1];
                        dp[i][j]=3;
                    }
                }
        }
        lcs(m,n);
 
    }
    return 0;
}

 这是最简单的情况,只要求构造一条最长子序列;

dp数组用来记录存进aa的值是来自上面还是前面还是左对角;

最后递归输出;

 

问题 H: Max Sum


时间限制: 1 Sec  内存限制: 33 MB



提交: 0  解决: 0  201501010119


提交状态讨论版 
  



题目描述 


给你一个序列 a[1],a[2],a[3]......a[n], 你要做的是求出最大字段和. 比如, 输入 6,-1,5,4,-7, 这个序列的最大字段和就是 6 + (-1) + 5 + 4 = 14.




输入 


The first line of the input contains an integer T(1<=T<=20) which means the number of test cases. Then T lines follow, each line starts with a number N(1<=N<=100000), then N integers followed(all the integers are between -1000 and 1000).




输出 

每组测试用例输出两行。  
第一行是"Case #:" # 表示测试用例的序数。 
 第二行包括三个数字,最大子段和,以及子段的起始位置和结束位置 
 例如:输入数组(6,-1,5,4,-7),输出14, 1, 4,其中14表示最大子段和,1表示和最大的子段从第1个数字开始,4表示和最大的子段到第4个数字结束,即(6, -1 , 5, 4)。 






样例输入 Copy 

2
5 6 -1 5 4 -7
7 0 6 -1 1 -6 7 -5



样例输出 Copy 

Case 1:
14 1 4
Case 2:
7 1 6
int a[1000];
int i,n;
int be,ed,k,b,sum;
int flag;
void maxx(int a[],int n)
{
    for(i=0;i<n;i++)
    {
        b=b+a[i];
        if(b>sum)
        {
            sum=b;
            ed=i+1;
            be=k+1;
        }
        if(b<0)
        {
            b=0;
            k=i+1;
        }
    }
    return ;
}

int main()
{
    int t;
    cin>>t;
    flag=0;
    while(t--)
    {
        cin>>n;
        for(i=0;i<n;i++)
            cin>>a[i];
         be=0,ed=0,k=0,b=0,sum=-1;
        maxx(a,n);
        flag++;
        cout<<"Case "<<flag<<":"<<endl<<sum<<" "<<be<<" "<<ed<<endl;
    }
    return 0;


 

posted @ 2019-04-21 22:22  RAIN-code  阅读(406)  评论(0编辑  收藏  举报