PTA 基础题集

7-1 厘米换算英尺英寸 (15 point(s))

感觉不值15分emm,明白inch/12一定是小于1的即可

#include<iostream>
using namespace std;
int main()
{
    int a;
    cin>>a;
    int foot,inch;
    foot=a/100.0/0.3048;
    inch=(a/100.0/0.3048-foot)*12;
    cout<<foot<<' '<<inch<<endl;
    return 0;
}

7-7 12-24小时制 (15 point(s))

#include<cstdio>
using namespace std;
int main()
{
    int h,m;
    scanf("%d:%d",&h,&m);
    if(h>=13) printf("%d:%d PM\n",h-12,m);
    else if(h==12) printf("%d:%d PM\n",h,m);
    else printf("%d:%d AM\n",h,m);
    return 0;
}
/*
12点	Wrong Answer	1 ms	256 KB
*/

7-17 爬动的蠕虫 (15 point(s))

每两分钟能上去u-d,从n-u到u只需要1min,计算1~n-u里面有多少个u-d,向上取整,次数为cnt,答案就是2*cnt+1

#include<iostream>
using namespace std;
int main()
{
    int n,u,d;
    cin>>n>>u>>d;
    int k=n-u;
    if(k<0){
        cout<<1<<endl;
        return 0;
    }

    int cnt=(k+u-d-1)/(u-d);
    int t=2*cnt+1;
    cout<<t<<endl;
    return 0;
}
//没有考虑小于一步到位的情况

7-18 二分法求多项式单根 (20 point(s))

退出的地方我没考虑好(忘记当时怎么错的了)

应该是最后的(left+right)/2

#include<cstdio>
#include<iostream>
using namespace std;
double a3,a2,a1,a0;
double f(double x)
{

    return (double)a3*x*x*x+a2*x*x+a1*x+a0;
}
int main()
{

    scanf("%lf%lf%lf%lf",&a3,&a2,&a1,&a0);
    double s,t;
    scanf("%lf%lf",&s,&t);
    if(f(s)==0) {printf("%.2lf\n",s);return 0;}
    if(f(t)==0) {printf("%.2lf\n",t);return 0;}

    double left=s,right=t;
    //cout<<f(left)<<' '<<f(right)<<endl;
    double mid;
    while(right-left>=1e-3)
    {
        mid=(left+right)/2;
        //cout<<f(mid)<<endl;
        if(f(mid)==0) {printf("%.2lf\n",mid);return 0;}          //f(mid==0) 退出 错误
        else if(f(left)*f(mid)<0) right=mid;
        else if(f(mid)*f(right)<0) left=mid;
    }
    if(right-left<1e-3) printf("%.2lf\n",(left+right)/2);
    return 0;
}

7-20 打印九九口诀表 (15 point(s))

这题复习了对齐emm

#include<cstdio>
int main()
{
    int n;
    scanf("%d",&n);
    for(int i=1;i<=n;++i)
    {
        for(int j=1;j<=i;++j)
        {
            printf("%d*%d=%-4d",j,i,i*j);
        }
        printf("\n");
    }
    return 0;
}

7-22 龟兔赛跑 (20 point(s))

规律水题,每270min兔子和乌龟在同一位置,所以只需要把前270分钟兔子跑的距离给弄清楚即可

每次兔子休息三十分钟都会被乌龟超过,当它第80min开始跑到90min时赶上乌龟,问题重置。

#include<iostream>
#include<cstdio>
using namespace std;
int t;
int tu(int t)
{
    int rnd=t/90;
    int ans=270*rnd;
    t%=90;
    int re=0;
    if(t>0&&t<=10) re=9*t;
    else if(t>10&&t<40) re=90;
    else if(t>=40&&t<=50) re=9*t-270;
    else if(t>50&&t<80) re=180;
    else if(t>=80&&t<90) re=9*t-540;
    return ans+=re;
}
int main()
{
    cin>>t;

    int gui=t*3;
    int tut=tu(t);
    //cout<<tut;
   // cout<<tut<<endl;
    if(tut<gui) printf("@_@ %d\n",gui);
    else if(tut>gui) printf("^_^ %d\n",tut);
    else printf("-_- %d\n",gui);
    return 0;
}

7-23 币值转换 (20 point(s))

做这道题才发现自己其实不太会读;而且超级不擅长找规律。。。

参考别人的,当时没记录下来是谁,发现雷同告诉我意识_(:з」∠)_

思路:用result存储答案,考虑每一位是否有数值输出,每一位是否有单位输出

当前位不是0,除了个位都要输出单位;

当前位是0:

如果是万位,一定会输出万,万位的0不读出

如果不是万位,不是千位,也不是个位,且前面一位非0那么本位会输出0

前面一位是0,本位什么都不输出

注意:如果是0,直接输出0

#include<iostream>
using namespace std;
int n;
char num[10];
char unit[10]={0,0,'S','B','Q','W','S','B','Q','Y'};      //1是个位,2是十位
char result[17];
int cur=0,bitnum=0,pre;
int k=0;
int main()
{
    for(int i=0;i<10;++i)
        num[i]=i+'a';
    cin>>n;
    if(!n)  {cout<<num[0]<<endl; return 0;}
    while(n)
    {
        cur=n%10;
        n/=10;
        bitnum++;
        if(cur)                                     //当前位有数值,只要不是个位,就一定会有单位
        {
            if(bitnum>1) result[k++]=unit[bitnum];
            result[k++]=num[cur];
        }
        else                                        //当前位为0,如果是万则要存单位,不用存数字
        {
            if(bitnum==5)
                result[k++]=unit[bitnum];
            else if(bitnum!=4&&bitnum!=1&&pre!=0)   //若不为万位,千位,个位,且前一位不为0;第一个为0的存数字不存单位(千位为0和个位为0除外)
                result[k++]=num[cur];

        }
        pre=cur;
    }
    for(int i=k-1;i>=0;--i)
        cout<<result[i];
    cout<<endl;
    return 0;
}

7-26 单词长度 (15 point(s))

stringstream好方便啊。。。要提前用s.erase(迭代器)把最后一个删掉

#include<cstdio>
#include<iostream>
#include<string>
#include<sstream>

using namespace std;
int main()
{
    string s;
    getline(cin,s);
    string::iterator it;
    it=s.end()-1;
    s.erase(it);
    stringstream ss(s);
    string a;
    int flag=0;
    while(ss>>a)
    {
        if(!flag)
        {
             cout<<a.size();
             flag++;
        }
        else
            cout<<' '<<a.size();
    }
    return 0;
}

n

/*
空格+. 醉了

这题的测试点好多啊
排除连续空格
开头结尾的空格
只有一个单词
卡在了空句子的测试点 只有一个句号的情况下不是应该输出0吗?
*/
#include<cstdio>
#include<iostream>
#include<string>

using namespace std;
int main()
{
    string s;
    getline(cin,s);
    //cout<<s<<endl;
    int len=s.size();
    int ans=0,flag=1;
    for(int i=0;i<len-1;++i)            //不需要考虑.
    {

        if(s[i]!=' ')
            ++ans;
        else if(ans)                    //如果等于空格,是第一个空格的话ans就会大于0,就把刚结束的单词个数给输出,输出后置0,这个样子就跳过重复的空格了
        {
            if(flag)
            {
                cout<<ans;
                flag=0;
            }
            else cout<<' '<<ans;
            ans=0;
        }
    }
    if(ans)                              //考虑最后一个单词后无空格的情况
    {
        if(flag)
            cout<<ans<<endl;
        else
            cout<<' '<<ans<<endl;
    }

    return 0;
}

7-27 冒泡法排序 (20 point(s))

复习了一波冒泡排序,把最小的顶到最前面

#include<iostream>
#include<algorithm>
using namespace std;
int n,k;
const int N =110;
int a[N];
void bubble_sort()
{
//    for(int i=n-1;i>=n-i-k+1;--i)
//    {
//        for(int j=0;j<i;++j)
//            if(a[j]>a[j+1])
//                swap(a[j],a[j+1]);
//    }
    for(int i=0;i<k;++i)
        for(int j=0;j<n-i-1;++j)
        {
            if(a[j]>a[j+1])
                swap(a[j],a[j+1]);
        }


}

int main()
{

    cin>>n>>k;
    for(int i=0;i<n;++i)
        cin>>a[i];
    bubble_sort();
    for(int i=0;i<n;++i)
    {
        if(i)
            cout<<' '<<a[i];
        else
            cout<<a[i];
    }
    cout<<endl;
    return 0;
}

7-28 猴子选大王 (20 point(s))

注意it每操作一次(涉及位置变更),都要注意是否到了最后一个,是的话置为最初的

/*
总结:删除操作传入迭代器,而迭代器所指向的位置在删除前后是不发生改变的,
改变的只是容器中的元素值,删除相应元素后,被删元素后面的所有元素复制到被删除元素的位置上去,
同时指向容器尾部的迭代器也移动到新的尾部位置。
*/
#include<iostream>
#include<vector>
using namespace std;
vector<int> v;
int main()
{
    int n;
    cin>>n;
    for(int i=1;i<=n;++i)
        v.push_back(i);
    int id=0;
    vector<int>::iterator it;
    it=v.begin();
    while(v.size()>1)
    {
        for(int i=1;i<3;++i)
        {
            ++it;
            if(it==v.end()) it=v.begin();
        }
        it=v.erase(it);
        if(it==v.end()) it=v.begin();
    }
    cout<<*it<<endl;
    return 0;

}

7-29 删除字符串中的子串 (20 point(s))

感慨一句,stl太强了

#include<iostream>
#include<string>
using namespace std;
int main()
{
    string a,b;
    getline(cin,a);
    getline(cin,b);
//    cout<<a<<endl;
//    cout<<b<<endl;
    int i;
    while((i=a.find(b))!=string::npos)  //没有加括号是不行的
    {
        a.replace(i,b.size(),"");
    }
    cout<<a<<endl;
    return 0;
}

7-35 有理数均值 (20 point(s))

#include<iostream>
#include<algorithm>
#include<cstdio>
using namespace std;
int gcd(int a,int b)
{
    if(b==0) return a;
    else return gcd(b,a%b);
}
int add(int &a,int &b,int c,int d)        //将答案保存在a,b中
{

    int x=a*d+b*c;
    int y=b*d;
    a=x/gcd(x,y);
    b=y/gcd(x,y);
}
int main()
{
    int n;
    int a=0,b=0;
    scanf("%d",&n);
    int x=n;
    while(x--)
    {
        if(!b)
            scanf("%d/%d",&a,&b);
        else
        {
            int c,d;
            scanf("%d/%d",&c,&d);
            add(a,b,c,d);
        }

    }
    int tmp=gcd(a,n*b);
    a/=tmp,b=n*b/tmp;
    if(b==1) printf("%d\n",a);
    else printf("%d/%d",a,b);
    return 0;
}

7-36 复数四则运算 (15 point(s))

这种题就是要抽取出重复的写成子函数,减少代码量

/*
一个是判定实部和虚部是否为0的时候是要将它们保留1位小数后的数字比对才行。
*/
#include<iostream>
#include<cstdio>
using namespace std;
void print(double a,double b)
{
    if(b<0) printf("(%.1lf%.1lfi)",a,b);
    else printf("(%.1lf+%.1lfi)",a,b);
}
void ppprint(double a,double b)
{
    if(b<0.05&&b>-0.05) printf("%.1lf\n",a);
    else if(a<0.05&&a>-0.05) printf("%.1lfi\n",b);
    else{
        if(b<0) printf("%.1lf%.1lfi",a,b);
        else printf("%.1lf+%.1lfi",a,b);
        printf("\n");
    }
}
int main()
{
    double a,b,c,d;
    cin>>a>>b>>c>>d;
    double a1=a+c,b1=b+d;
    double a2=a-c,b2=b-d;
    double a3=a*c-b*d,b3=b*c+a*d;
    double a4=(a*c+b*d)/(c*c+d*d),b4=(b*c-a*d)/(c*c+d*d);
    print(a,b); printf(" + "); print(c,d); printf(" = "); ppprint(a1,b1);
    print(a,b); printf(" - "); print(c,d); printf(" = "); ppprint(a2,b2);
    print(a,b); printf(" * "); print(c,d); printf(" = "); ppprint(a3,b3);
    print(a,b); printf(" / "); print(c,d); printf(" = "); ppprint(a4,b4);
    return 0;
//    if(!r&&!i)
//        printf("(%.1lf%c%.1lfi) + (%.1lf%c%.1lfi) = 0.0\n",a,b<0?'\0':'+',b,c,d<0?'\0':'+',d);
}

7-37 整数分解为若干项之和 (20 point(s))

dfs 需要记录累加和是多少,下一个数是多少(判断该不该加上去),以及记录这个数是第几个

#include<iostream>
using namespace std;
int a[35];
int flag=0;
int n;
void dfs(int len,int pos,int next)
{
    if(pos+next>n)
        return ;
    a[len++]=next;
    if(pos+next==n)
    {
        cout<<n<<'=';
        for(int i=0;i<len;++i)
        {
            if(!i) cout<<a[i];
            else cout<<'+'<<a[i];
        }
        flag++;
        if(!(flag%4)||next==n) cout<<endl;
        else cout<<';';
    }
    if(pos+next<n)
    {
        pos+=next;
        for(int i=next;i<=n-pos;++i)
            dfs(len,pos,i);
    }
}
int main()
{
    cin>>n;
    for(int i=1;i<=n/2;++i)
        dfs(0,0,i);
    dfs(0,0,n);
    return 0;
}

7-38 数列求和-加强版 (20 point(s))

本来以为要用大数加法的,但这道题比较特别。

#include<iostream>
using namespace std;
typedef long long LL;
int a,n;
const int N=1e5+10;
int arr[N];
int main()
{
    cin>>a>>n;
    for(int i=0;i<n;++i)
    {
        arr[i]+=a*(n-i);                        //必须是+=
        arr[i+1]+=arr[i]/10;                    //+=
        arr[i]%=10;
    }
    if(n==0) {cout<<0<<endl;return 0;}
    if(arr[n]) cout<<arr[n];                    
    for(int i=n-1;i>=0;--i)
        cout<<arr[i];
    cout<<endl;
    return 0;
}

猜你喜欢

转载自blog.csdn.net/iroy33/article/details/88256500