科大晋校第四次周训(C语言网)

本想通过一种题,掌握一类题,可你们偏偏钻题目漏洞。按照我提出的问题去想,不然下次出一个相同的题,却因为题目给的范围无法下手,你只会写三组数据,若给你一百万组数据怎么办?

问题 1024: [编程入门]矩阵对角线求和

时间限制: 1Sec 内存限制: 128MB 提交: 6052 解决: 3974

题目描述
求一个3×3矩阵对角线元素之和。
输入
矩阵
输出
主对角线 副对角线 元素和
样例输入
1 2 3
1 1 1
3 2 1
样例输出
3 7

题解:本题你可以直接通过下标计算出来,但是题目给的是三组数据,若给你一堆数据怎么办?还有这很明显是二维数组,不要定义一位数组去输入,后面去找行与列下标的关系不好找,。

很明显
主对角线下标关系就是列下标等于行下标:j==i ,时就给他累加
副对角线下标关系就是行下标等于n减列下标,即 j == n-i时,就进行累加

要找个全面普遍的通解,而非只能计算三组数据。。

#include <iostream>
#include <string>
#include <algorithm>
#include <cstdio>
#include <vector>
#include <queue>
using namespace std;
typedef long long ll;
#define mod 9999999
#define maxn 10005
int main()
{
    int a[3][3];
    int sum1=0,sum2=0;
    for(int j=0;j<3;j++)
    {
        for(int i=0;i<3;i++)
        {
            cin>>a[j][i];
            if(j==i)
                sum1+=a[j][i];
            if(j==2-i)
                sum2+=a[j][i];
        }
    }
    cout<<sum1<<" "<<sum2<<endl;
    return 0;
}

问题 1044: [编程入门]三个字符串的排序

时间限制: 1Sec 内存限制: 128MB 提交: 3872 解决: 1820

题目描述
输入三个字符串,按由小到大的顺序输出
输入
3行字符串
输出
按照从小到大输出成3行
样例输入
cde
afg
abc
样例输出
abc
afg
cde

题解:当然可以直接三个if判断进行代替两个for()循环,。但是数据多了你又怎么处理。。。所以通解就是用冒泡排序来写。

排序,就是按照字符对应的ASCII值比较大小,a<b,x<y,而比较ASCII值可以用C语言的strcmp()函数,这个函数会比较两个字符串的ASCII值,若第一个位置可以比较出来就结束,若第一个字符相同,则会进行比较下一个字符,直到结束。他的返回值为<0,>0,==0,
用法eg:char a[20],b[20]; strcmp(a,b);

比较出来后对不符合条件的进行排序,不符合条件的进行交换数据,此处就用到了冒泡排序,关于冒泡排序写法建议大家去csdn上面找一些好的博客去学习一下,非常有用。

还有字符串的赋值最好用字符串复制函数strcpy(a,b);意思是将b复制给a.若用==赋值会出现问题。

注意:使用刚刚说的那两个函数需要加头文件string.h,即 #include <string.h>

#include <iostream>
#include <string>
#include <string.h>
#include <algorithm>
#include <cstdio>
#include <vector>
#include <queue>
using namespace std;
typedef long long ll;
#define mod 9999999
#define maxn 10005
int main()
{
    char a[3][100],b[100];
    for(int i=0;i<3;i++)
        cin>>a[i];
        
    for(int j=0;j<3;j++)
    {
        for(int i=2;i>=j+1;i--)
        {
            if(strcmp(a[i],a[i-1])<0)
            {
                strcpy(b,a[i]);
                strcpy(a[i],a[i-1]);
                strcpy(a[i-1],b);
            }
        }
    }
    for(int i=0;i<3;i++)
    {
        cout<<a[i]<<endl;
    }
    return 0;
}

问题 1131: 【C语言训练】斐波纳契数列

时间限制: 1Sec 内存限制: 128MB 提交: 1352 解决: 791

题目描述
斐波纳契数列
1,1,2,3,5,8,13,21,34,55,89……这个数列则称为“斐波纳契数列”,其中每个数字都是“斐波纳契数”。

输入
一个整数N(N不能大于40)

输出
由N个“斐波纳契数”组成的“斐波纳契数列”。

样例输入
6
样例输出
1 1 2 3 5 8

题解:此题最简单:斐波那契数列应该不陌生了吧,说过好几次了,如果只求第几项那就简单多了,而这道题要求都要打印出来,所以可以判断一下,1,2,和大于2的时候,。大于2可以直接for循环从下标为2开始,另当前项等于前两项和就行,然后计算一个输出一个,可以少些一个for循环进行输出。当然在循环之前也得将第一二项输出,。

控制行末空格,可以在for循环里判断循环变量来控制,也可以在循环外面先输出第一项循环内每次输出时都先输出空格再输出数据,这样可以去掉行末空格。

拓展:若求第n项的值,可以for循环,也可以运用递归,最好掌握递归用法,大二的数据结构与算法里面许多数据结构都用到了递归,,,,可见其重要性。。最重要的是理解递归的执行步骤,我不做过多解释,想详细了解可以去CSDN上面去搜索优秀的博客去看看,或者利用B站,这是一个巨大的资源库。。。

接下来我写一下递归如何求斐波那契数列第n项值
拓展:

#include <iostream>
#include <string>
#include <string.h>
#include <algorithm>
#include <cstdio>
#include <vector>
#include <queue>
using namespace std;
typedef long long ll;
#define mod 9999999
#define maxn 10005

int f(int n)//1 1 2 3 5 8
{
    if(n==1||n==2)
        return 1;

    return f(n-1)+f(n-2);
}
int main()
{
    cout<<f(6)<<endl;

    return 0;
}

本题题解:

#include <iostream>
#include <string>
#include <string.h>
#include <algorithm>
#include <cstdio>
#include <vector>
#include <queue>
using namespace std;
typedef long long ll;
#define mod 9999999
#define maxn 10005
int main()
{
    int a[maxn],n;
    cin>>n;
    a[0]=1;
    a[1]=1;
    if(n==1)
        cout<<a[0]<<endl;
    else if(n==2)
        cout<<a[0]<<" "<<a[1]<<endl;
    else
    {
        cout<<a[0]<<" "<<a[1];
        
        for(int i=2;i<n;i++)
        {
            a[i]=a[i-1]+a[i-2];
            cout<<" "<<a[i];
        }
        cout<<endl;
    }
    return 0;
}

问题 1141: 【C语言训练】百钱百鸡问题

时间限制: 1Sec 内存限制: 128MB 提交: 1106 解决: 716

题目描述
中国古代数学家张丘建在他的《算经》中提出了著名的“百钱买百鸡问题”:鸡翁一,值钱五,鸡母一,值钱三,鸡雏三,值钱一,百钱买百鸡,问翁、母、雏各几何?

输入
无输入

输出
给出所有的解,每组解占一行
解的顺序:按“字典序”排列,即公鸡数少的在前;公鸡数相同,母鸡数少的在前
格式:
cock=%d,hen=%d,chicken=%d\n

样例输入

样例输出
cock=0,hen=25,chicken=75
cock=4,hen=18,chicken=78
cock=8,hen=11,chicken=81
cock=12,hen=4,chicken=84

题解:本题很简单,就是简单的暴力,所谓暴力就是让程序将所有情况都执行一下,排除不符合条件的,将符合条件的输出。

定义三个变量,代表公鸡,母鸡,小鸡,即三重for循环,再用if判断一下,关键是if的条件。。。

百钱买百鸡:就是一百块钱买一百只鸡。。
所以你要将条件列出来:
1、钱的总数是100
2、鸡的总数是100
3、小鸡不能买到半只。。。
即:i+j+k==100,即鸡的数目,钱的总数:sum=i5+j3+k/3;,以及小鸡不能半只:即对三取余要等于0即:k%3 == 0,符合条件的输出就好。

#include <iostream>
#include <string>
#include <string.h>
#include <algorithm>
#include <cstdio>
#include <vector>
#include <queue>
using namespace std;
typedef long long ll;
#define mod 9999999
#define maxn 10005
int main()
{
    int p=0,sum=0;
    int i,j,k;
    for(i=0;i<100;i++)
    {
        for(j=0;j<34;j++)
        {
            for(k=0;k<300;k++)
            {
                sum=i*5+j*3+k/3;
                if(sum==100&&(i+j+k)==100&&k%3==0)
                {
                    cout<<"cock="<<i<<","<<"hen="<<j<<","<<"chicken="<<k<<endl;
                }
            }
        }
    }
    
    return 0;
}

问题 1150: 【C语言训练】计算t=1+1/2+1/3+…+1/n

时间限制: 1Sec 内存限制: 128MB 提交: 1226 解决: 619

题目描述
计算t=1+1/2+1/3+…+1/n

输入
整型变量n

输出
t(保留六位小数)

样例输入
10
样例输出
2.928968

题解:此题简单。注意计算的是小数:所以以防万一,将1换为1.0,。 t+=1.0/i;

控制小数位数:最好用printf,double,最好用 %lf来控制

#include <iostream>
#include <string>
#include <string.h>
#include <algorithm>
#include <cstdio>
#include <vector>
#include <queue>
using namespace std;
typedef long long ll;
#define mod 9999999
#define maxn 10005

double f(double n)
{
    double t=0;
    
    for(int i=1;i<=n;i++)
    {
        t+=1.0/i;
    }
    return t;
}

int main()
{
    int n;
    cin>>n;
    
    printf("%.6lf\n",f(n));
    
    return 0;
}

问题 1157: 【亲和数】

时间限制: 1Sec 内存限制: 128MB 提交: 2932 解决: 1488

题目描述
古希腊数学家毕达哥拉斯在自然数研究中发现,220的所有真约数(即不是自身的约数)之和为:

1+2+4+5+10+11+20+22+44+55+110=284。

而284的所有真约数为1、2、4、71、 142,加起来恰好为220。人们对这样的数感到很惊奇,并称之为亲和数。一般地讲,如果两个数中任何一个数都是另一个数的真约数之和,则这两个数就是亲和数。
你的任务就编写一个程序,判断给定的两个数是否是亲和数

输入
输入数据第一行包含一个数M,接下有M行,每行一个实例,包含两个整数A,B; 其中 0 <=A,B <=600000 ;

输出
对于每个测试实例,如果A和B是亲和数的话输出YES,否则输出NO。

样例输入
2
220 284
100 200
样例输出
YES
NO

题解:本题也很简单。就是找自己的约数,方法当然是从1到自己,每次都对自己取余,取余等于零的说明能除尽,就是约数,将他累加起来,就行。。

最后将两个和判断一下是否等于对方的数,是就输出YES.否则输出NO…

#include <iostream>
#include <string>
#include <string.h>
#include <algorithm>
#include <cstdio>
#include <vector>
#include <queue>
using namespace std;
typedef long long ll;
#define mod 9999999
#define maxn 10005
void f(int num1,int num2)
{
    int a=0,b=0;
    
    for(int i=1;i<num1;i++)
    {
        if(num1%i==0)
        a+=i;
    }
    
    for(int i=1;i<num2;i++)
    {
        if(num2%i==0)
        b+=i;
    }
    
    if(a==num2&&b==num1)
        cout<<"YES"<<endl;
    else
        cout<<"NO"<<endl;
}
int main()
{
    int n;
    int a[maxn],b[maxn];
    
    cin>>n;
    for(int i=0;i<n;i++)
    {
        cin>>a[i]>>b[i];
        f(a[i],b[i]);
    }
    
    return 0;
}

问题 1161: 【回文数(二)】

时间限制: 1Sec 内存限制: 128MB 提交: 679 解决: 261

题目描述
若一个数(首位不为零)从左向右读与从右向左读都一样,我们就将其称之为回文数。
例如:给定一个10进制数56,将56加65(即把56从右向左读),得到121是一个回文数。
又如:对于10进制数87:
STEP1:87+78 = 165         STEP2:165+561 = 726
STEP3:726+627 = 1353        STEP4:1353+3531 = 4884
在这里的一步是指进行了一次N进制的加法,上例最少用了4步得到回文数4884。
写一个程序,给定一个N(2<=N<=16)进制数M,求最少经过几步可以得到回文数。如果在30步以内(包含30步)不可能得到回文数,则输出“Impossible!”

输入
共两行
第一行为进制数N(2<=N<=16)
第二行为N进制数M(0<=M<=maxlongint)

输出
共一行,为“STEP=经过的步数”或“Impossible!”

样例输入
9
87
样例输出
STEP=6

题解:此题似乎很难,先放下,但我会尽量做出他来,大家也可以参考一下。。

问题 1171: 【蟠桃记】

时间限制: 1Sec 内存限制: 128MB 提交: 725 解决: 448

题目描述
喜欢西游记的同学肯定都知道悟空偷吃蟠桃的故事,你们一定都觉得这猴子太闹腾了,其实你们是有所不知:悟空是在研究一个数学问题!
什么问题?他研究的问题是蟠桃一共有多少个!
不过,到最后,他还是没能解决这个难题,呵呵-
当时的情况是这样的:
第一天悟空吃掉桃子总数一半多一个,第二天又将剩下的桃子吃掉一半多一个,以后每天吃掉前一天剩下的一半多一个,到第n天准备吃的时候只剩下一个桃子。聪明的你,请帮悟空算一下,他第一天开始吃的时候桃子一共有多少个呢?

输入
输入数据有多组,每组占一行,包含一个正整数n(1<n<30),表示只剩下一个桃子的时候是在第n天发生的

输出
对于每组输入数据,输出第一天开始吃的时候桃子的总数,每个测试实例占一行。

样例输入
2
4
样例输出
4
22

题解:每次吃剩余的一半多一个,他正着来直到为1的时候,那咱就倒着来,直到倒到起始总数,输出就行。。

每次都是剩余的一半多一个,那么倒着来照样有规律,即如下图。

在这里插入图片描述

看余下的那一列的数字,倒着来看:1 4 10 22,22为总数,如何从1到4,从4到10,从10到22,很明显,就是1+1再乘2,4+1再乘2,10+1再乘2,所以就可以写了。。。

循环里,从1开始都让他加1乘2,直到结束,再看一下,算了几次,n为4的时候,循环三次就够了,所以循环次数控制为for(int i=1;i<n;i++)就行了。

#include <iostream>
#include <string>
#include <string.h>
#include <algorithm>
#include <cstdio>
#include <vector>
#include <queue>
using namespace std;
typedef long long ll;
#define mod 9999999
#define maxn 10005

int f(int n)
{
    int x=1;
    
    for(int i=1;i<n;i++)
    {
        x=(x+1)*2;
    }
    
    return x;
}

int main()
{
    int n;
    
    while(cin>>n)
    {
        cout<<f(n)<<endl;
    }
    
    return 0;
}

问题 1214: 恺撒密码

时间限制: 1Sec 内存限制: 128MB 提交: 260 解决: 143

题目描述
恺撒生活在充满危险和阴谋的时代. 恺撒面对的最困难的问题是生存. 为了生存, 他决定创造一种密码. 这种密码听起来难以置信, 如果不知道方法, 没有人可以破解.

你是恺撒军队的一个上尉. 你的工作是解密消息并将之提供给将军. 密码很简单. 对明文的每个字母右移5个位置以创建密文 (如字母’A’, 密 文是’F’). 有如下对应:

密文
A B C D E F G H I J K L M N O P Q R S T U V W X Y Z

明文
V W X Y Z A B C D E F G H I J K L M N O P Q R S T U

只有字母需要移位, 其它字符保持不变, 所有字母均是大写.

输入
输入为至多100组数据. 每组数据有如下格式, 中间无空行.

一组数据有3部分:

起始行 - 单独一行: “START”
密文 - 单独一行, 包含1到200个字符, 组成恺撒的消息.
结束行 - 单独一行: “END”

最后一组输入是单独一行: “ENDOFINPUT”.

输出
对每组数据有一行输出. 即恺撒的原始消息.

样例输入
START
NS BFW, JAJSYX TK NRUTWYFSHJ FWJ YMJ WJXZQY TK YWNANFQ HFZXJX
END
START
N BTZQI WFYMJW GJ KNWXY NS F QNYYQJ NGJWNFS ANQQFLJ YMFS XJHTSI NS WTRJ
END
START
IFSLJW PSTBX KZQQ BJQQ YMFY HFJXFW NX RTWJ IFSLJWTZX YMFS MJ
END
ENDOFINPUT
样例输出
IN WAR, EVENTS OF IMPORTANCE ARE THE RESULT OF TRIVIAL CAUSES
I WOULD RATHER BE FIRST IN A LITTLE IBERIAN VILLAGE THAN SECOND IN ROME
DANGER KNOWS FULL WELL THAT CAESAR IS MORE DANGEROUS THAN HE

题解:此题也不难,就是题目有点难理解,绕,看懂题目就好。

就是将输入的字符串每一个字符都向前移五位eg: K-> F,就这个意思,但是有特殊情况A,B,C,D,E,这五项减五时候会减到其对应ASCII码值对应的字符,并不是A-Z,所以要特别处理一下。而F-Z,都是可以直接减的。

注意事项cin输入不了空格,建议使用getline()函数,或者puts()函数,都可以,puts()函数使用最好加上头文件:#include < cstdio >或者#include <stdio.h>,都行;使用string,最好加上#include < string >,

#include <iostream>
#include <string>
#include <string.h>
#include <algorithm>
#include <cstdio>
#include <vector>
#include <queue>
using namespace std;
typedef long long ll;
#define mod 9999999
#define maxn 10005
int main()
{
    string str;
    string start,endd;
    
    while(cin>>str)
    {
        getline(cin,start);
        getline(cin,str);
        getline(cin,endd);
//        if(endd.compare("ENDOFINPUT")==0)
//        {
//            break;
//        }
        for(int i=0;i<str.length();i++)
        {
            if(str[i]>='F'&&str[i]<='Z')
                str[i]=str[i]-5;
            else
            {
                if(str[i]=='A')
                    str[i]='V';
                if(str[i]=='B')
                    str[i]='W';
                if(str[i]=='C')
                    str[i]='X';
                if(str[i]=='D')
                    str[i]='Y';
                if(str[i]=='E')
                    str[i]='Z';
            }
        }
        
        cout<<str<<endl;
    }
    //A B C D E F G H I J K L M N O P Q R S T U V W X Y Z
    //NS BFW, JAJSYX TK NRUTWYFSHJ FWJ YMJ WJXZQY TK YWNANFQ HFZXJX
    //IN WAR, EVENTS OF IMPORTANCE ARE THE RESULT OF TRIVIAL CAUSES
    return 0;
}

问题 1100: 采药

时间限制: 1Sec 内存限制: 128MB 提交: 1997 解决: 578

题目描述

辰辰是个天资聪颖的孩子,他的梦想是成为世界上最伟大的医师。为此,他想拜附近最有威望的医师为师。医师为了判断他的资质,给他出了一个难题。医师把他带到一个到处都是草药的山洞里对他说:“孩子,这个山洞里有一些不同的草药,采每一株都需要一些时间,每一株也有它自身的价值。我会给你一段时间,在这段时间里,你可以采到一些草药。如果你是一个聪明的孩子,你应该可以让采到的草药的总价值最大。”

如果你是辰辰,你能完成这个任务吗?

输入

输入第一行有两个整数T(1 <= T <= 1000)和M(1 <= M <= 100),用一个空格隔开,T代表总共能够用来采药的时间,M代表山洞里的草药的数目。接下来的M行每行包括两个在1到100之间(包括1和100)的整数,分别表示采摘某株草药的时间和这株草药的价值。

输出
输出一行,这一行只包含一个整数,表示在规定的时间内,可以采到的草药的最大总价值。

样例输入
70 3
71 100
69 1
1 2
样例输出
3
提示
对于30%的数据,M <= 10;

对于全部的数据,M <= 100。

题解:此题应该不简单,我这样写只能骗百分之18的分数,就是将其写成结构体,对其price进行了冒泡排序,使大数在前,优先取大数,。。这样肯定有问题。。。。但是可以骗到一定的分数。。

正确题解:本题又用到了数据结构与算法,动态规划dp递归,以及01背包算法,目前先放下吧,非常难,不好理解!!!

正确做法会尽快写出来,尽情期待!!!

#include <iostream>
#include <string>
#include <string.h>
#include <algorithm>
#include <cstdio>
#include <vector>
#include <queue>
using namespace std;
typedef long long ll;
#define mod 9999999
#define maxn 10005

struct caoyao
{
    int time;
    int price;
}a[105];

int main()
{
    int t,m,total=0;
    cin>>t>>m;
    for(int i=0;i<m;i++)
    {
        cin>>a[i].time>>a[i].price;
    }
    for(int i=0;i<m;i++)//排序
    {
        for(int j=m-1;j>i;j--)
        {
            if(a[j].price>a[j-1].price)
                swap(a[j],a[j-1]);
        }
    }
    for(int i=0;i<m;i++)
    {
        if(t<=0)
            break;
        if(a[i].time<=t)
        {
            t-=a[i].time;
            total+=a[i].price;
        }
    }
    
    cout<<total<<endl;
    
    return 0;
}


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值