本文代码均省略库和namespace声明,其中read()函数是读入数值的函数。


A 中间数
从标准输入设备读入三个整数a、b、c,找出中间数并输出。 中间数定义为: 若三数不相等,则第2大的数是中间数;若有两个数相等,则最大数作为中间数。
对应每一组测试数据,输出其中间数。

确实水,但是需要注意题目对中间数的定义,不要想当然地直接输出第二大的数……


    int a,b,c,T;
    int main()
    {
        for(read(T);T;--T)
        {
            read(a); read(b); read(c);
            if(a>b) swap(a,b);
            if(b>c) swap(b,c);
            if(a>b) swap(a,b);  // 手动排序
            printf("%d\n",(a==b||b==c)?c:b);
        }
        return 0;
    }

B 跳水打分问题
运动员跳水时,有n个评委打分,分数为10分制,且有两位小数。得分规则为:去掉最高分和最低分,求剩下分数的平均值,就是运动员的最终得分。
有多组测试数据。第一行是整数T (T <= 100),表示测试数据的组数,随后有T组测试数据。每一组测试数据占一行,分别为整数n和n个评委的打分,相邻数之间有一个空格。其中,2<n≤100。
对应每组输入,输出该运动员的得分,保留2位小数。

按题意模拟即可。


    int n,T;
    double sco[101],sum;
    int main()
    {
        for(read(T);T;--T)
        {
            read(n);
            sum=0;
            for (register int i=1;i<=n;++i) scanf("%lf",&sco[i]),sum+=sco[i];
            sort(sco+1,sco+n+1);
            sum-=sco[1]+sco[n];
            printf("%.2lf\n",sum/double(n-2));
        }
        return 0;
    }

C 最大公约数与最小公倍数
从标准输入设备读入两个正整数,求两数的最大公约数与最小公倍数。
有多组测试数据。输入的第一行是整数T(0<T≤100),表示测试数据的组数。每一组测试数据只有一行,分别为整数a和b,两数之间有一个空格。0<a,b≤32767。
对应每组输入,输出一行对应两数的最大公约数和最小公倍数,两数之间用一个空格隔开。

按题意模拟即可。注意 a*b=lcm(a,b)*gcd(a,b) 。


    int T,x,y,g;
    int gcd(int a,int b) {return b?gcd(b,a%b):a;}
    int main()
    {
        for(read(T);T;--T)
        {
            read(x); read(y);
            g=gcd(x,y);
            printf("%d %d\n",g,x/g*y);
        }
        return 0;
    }

D 分数运算
读入4个整数a、b、c、d和一个运算符(‘+’、‘-’、‘*’、‘/’中的一个),进行分数a/b和c/d的对应运算,输出最简结果。
有多组测试数据。输入的第一行是整数T(1<=T<=200),表示随后测试数据的组数。每组测试数据占一行,由四个正整数a,b,c,d和一个运算符组成,相邻数据间有一个空格。
对应每组测试数据,输出分数运算的最简结果,占一行。具体可参照样例。

注意输出格式,不是只输出结果,而是要输出算式。


    int T,a,b,c,d,ansa,ansb,g;
    char y;
    inline int abs(int x) { return x<0?-x:x; }
    int gcd(int i,int v) {return v?gcd(v,i%v):i;}
    int main()
    {
        for(read(T);T;--T)
        {
            read(a); read(b); read(c); read(d);
            y=getchar();
            switch(y)
            {
                case '+': ansa=a*d+b*c; ansb=b*d; break;
                case '-': ansa=a*d-b*c; ansb=b*d; break;
                case '*': ansa=a*c; ansb=b*d; break;
                case '/': ansa=a*d; ansb=b*c; break;
            }
            do{ g=gcd(abs(ansa),ansb); ansa/=g; ansb/=g; }while(g>1);
            if(ansb==1) printf("%d/%d%c%d/%d=%d\n",a,b,y,c,d,ansa);
            else printf("%d/%d%c%d/%d=%d/%d\n",a,b,y,c,d,ansa,ansb);
        }
        return 0;
    }

E 排列问题
读入两个非负大整数,判断其中一个是否能由另一个大整数内的数字重新排列得到。
有多组测试数据。输入的第一行是整数T(1<=T<=200),表示随后有T组测试数据。每组测试数据占两行,每行是一个非负大整数,位数不超过100。
对应每组测试数据,若其中一个大整数可以由另一个大整数重新排列得到,输出”Yes”,否则输出”No”。

按题意,需要统计两个大整数中 0 ~ 9 的出现次数是否相等。由于 0 可以排列在数字开头变为前导零,所以忽略 0 的出现次数。代码使用string类的 == 运算符快速解题。


    int T;
    string str1,str2;
    int main()
    {
        for(read(T);T;--T)
        {
            cin>>str1>>str2;
            sort(str1.begin(),str1.end());
            sort(str2.begin(),str2.end());
            while(str1[0]=='0') str1.erase(0,1);
            while(str2[0]=='0') str2.erase(0,1);
            printf(str1==str2?"Yes\n":"No\n");
        }
        return 0;
    }

F 开灯问题
有n盏灯, 编号为1~n. 第1个人把所有灯打开, 第2个人按下所有编号为2的倍数的开关(这些灯将被关掉), 第3个人按下所有编号为3的倍数的开关(其中关掉的灯将被打开, 开着的灯将被关闭), 依此类推. 一共有k个人, 问最后有哪些灯开着?
有多组测试数据. 输入的第一行是整数T(0<T≤100), 表示测试数据的组数. 每一组测试数据只有一行, 依次为正整数n和k, 两数之间有一个空格. k<=n<=1000.
对应每组输入, 输出一行还开着灯的编号, 按从小到大的顺序, 每个编号后有一个空格.

数字不大,就不写优化了。按题意,根据每个灯泡编号(假设为 d ),统计 1 ~ d 中出现过的 d 的因数个数即可。


    int T,n,k;
    int main()
    {
        for(read(T);T;--T)
        {
            read(n); read(k);
            for (register int i=1;i<=n;++i)
            {
                bool stat=0;
                for (register int v=1;v<=k&&v<=i;++v)
                    if(i%v==0) stat^=1;
                if(stat) printf("%d ",i);
            }
            putchar('\n');
        }
        return 0;
    }

G 蛇形填数
在n*n方阵里填入1,2,3,…,n*n, 要求填成蛇形. 例如 n=4 时方阵为:

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

有多组测试数据. 输入的第一行是整数T(1<=T<=20), 表示随后测试数据的组数. 每组测试数据占一行, 由正整数n组成. N<=20.
对应每组测试数据, 输出对应的蛇形矩阵, 每个数占四位, 右对齐.

蓝书原题,上一份蓝书上的std


    int amaxn;
    int main()
    {
        int n, x, y, tot = 0;
        scanf("%d", &n);
        memset(a, 0, sizeof(a));
        tot = ax = 0 = 1;
        while(tot < n * n)
        {
            while(x + 1 < n && !ax + 1) a++x = ++tot;
            while(y - 1 >= 0 && !ax) ax = ++tot;
            while(x - 1 >= 0 && !ax - 1) a--x = ++tot;
            while(y + 1 < n && !ax) ax = ++tot;
        }
        for(x = 0; x < n; x++)
        {
            for(y = 0; y < n; y++) printf("%3d", ax);
            printf("\n");
        }
        return 0;
    }

我自己写的这道题的代码暴躁了点,用的是搜索,而且较为复杂。


    int T,n,mat21;
    bool vis21;
    void sol(int val,int x,int y,int dir)
    {
        matx=val;
        visx=true;
        if(!visx+1&&x<n&&((dir==4&&(visx||y==n))||dir==1)) sol(val+1,x+1,y,1);
        else if (!visx&&y>1&&(dir==1||dir==2)) sol(val+1,x,y-1,2);
        else if (!visx-1&&x>1&&(dir==2||dir==3)) sol(val+1,x-1,y,3);
        else if (!visx&&y<n&&(dir==3||dir==4)) sol(val+1,x,y+1,4);
    }
    int main()
    {
        for(read(T);T;--T)
        {
            read(n);
            memset(vis,0,sizeof vis);
            sol(1,1,n,1);
            for (register int i=1;i<=n;++i)
            {
                for (register int v=1;v<=n;++v) printf("%d ",mati);
                putchar('\n');
            }
        }
        return 0;
    }

H 数据大搜索
一行字符串可能含有多个正整数, 请找出这些整数, 并输出它们的和.
有多组测试数据. 输入的第一行是整数T(1<=T<=100), 表示随后测试数据的组数. 每组测试数据占一行, 由一个可能含有空格的字符串构成, 该字符串可能含有多个数字子串, 每个数字子串的数字个数不超过16, 数字子串的个数不超过10, 字符串的长度不超过1000.
对应每组测试数据, 输出该字符串所包含整数的和. 如果该字符串没有包含数字, 请输出0.

根据题意直接魔改了我常用的 read() 函数塞进去,可能不太好看


    template<class _T>inline void read(_T &_a)
    {
        bool f=0; char _c=getchar(); _a=0;
        while(_c<'0'||_c>'9'){ if(_c=='-') f=1; _c=getchar(); }
        while(_c>='0'&&_c<='9'){ _a=(_a<<3)+(_a<<1)-'0'+_c; _c=getchar(); }
        if(f) _a=-_a;
    }


    int T;
    long long ans;
    int main()
    {
        for(read(T);T;--T)
        {
            ans=0;
            bool flag=true;
            while(flag)
            {
                long long _a=0; char _c=getchar();
                if(_c=='\n'||_c==EOF) break;
                while(_c<'0'||_c>'9') { _c=getchar(); if(_c=='\n'||_c==EOF) { flag=false; break; } }
                while(_c>='0'&&_c<='9'&&flag){ _a=(_a<<3)+(_a<<1)-'0'+_c; _c=getchar(); if(_c=='n'||_c==EOF) flag=false; }
                ans+=_a;
            }
            printf("%lld\n",ans);
        }
        return 0;
    }

I 旋转字符矩阵
读入一个n*n的字符矩阵, 绕矩阵中心顺时针旋转90度并输出结果.
有多组测试数据。第一行是整数T (T <= 100),表示测试数据的组数,随后有T组测试数据。每一组测试数据的第一行是正号数n, 随后是一个n*n的全由小写英文字符构成的字符矩阵, n < 100.
对应每组输入,输出绕矩阵中心顺时针旋转的字符矩阵, 每组给出完成后, 再输出一个空行.

按题意模拟即可


    int T,n;
    char t101;
    int main()
    {
        for(read(T);T;--T)
        {
            read(n);
            for (register int i=1;i<=n;++i)
            {
                for (register int v=1;v<=n;++v) ti=getchar();
                getchar();
            }
            for (register int i=1;i<=n;++i)
            {
                for (register int v=n;v;--v) putchar(tv);
                putchar('\n');
            }
            putchar('\n');
        }
        return 0;
    }

J 猴子选大王
在m只猴子聚在一起选大王, 商定规则如下: 大家围成一圈, 按顺时针从1编号, 第一次从编号为1的开始报数, 以后循环进行, 当报到n时退出圈子, 下一只则重新从1开始报数, 圈子中剩下的最后一只猴子则为大王.
有多组测试数据. 输入的第一行是整数T(1<=T<=100), 表示随后测试数据的组数. 每组测试数据占一行, 由正整数m和n组成, 两数之间有一个空格. 2 <= m,n <= 200.
对应每组测试数据, 输出选出的大王的猴子编号.

写了个比较丑的链表


    int T,n,m,nxt[201],now;
    bool out[201];
    int find(int id)
    {
        return out[nxt[id]]?nxt[id]=find(nxt[id]):nxt[id];
    }
    int main()
    {
        for(read(T);T;--T)
        {
            read(m); read(n);
            memset(out,0,sizeof out);
            for (register int i=1;i<m;++i) nxt[i]=i+1;
            nxt[m]=1;
            now=1;
            for(register int i=1;i<m;++i)
            {
                for (register int i=1;i<n;++i) now=find(now);
                out[now]=true;
                now=find(now);
            }
            printf("%d\n",now);
        }
        return 0;
    }

K 颠倒句子中的单词
读入一行英文句子,颠倒该句子的英文单词, 然后输出颠倒次序后的整个句子.
有多组测试数据.输入的第一行是整数T(1<=T<=20),表示随后测试数据的组数.每组测试数据是一行长度超过2, 但不超过1000的英文句子, 注意第一个单词前没有空格, 单词间的分隔符为一个空格, 结束也没有标点符号, 每个单词的长度不超过20.
对应每组测试数据, 输出一行颠倒次序的英文句子.

这题可以用 strtok() 很方便地做出来,可惜我做这题的时候还没能用上这个函数,于是手写了模拟。


    int T,len;
    char c[1005];
    int main()
    {
        for(read(T);T;--T)
        {
            len=0;
            do { c[++len]=getchar(); } while(c[len]!='\n'&&c[len]!=EOF);
            c[len--]='\0';
            for (register int i=len;i;--i)
                if(c[i]==' ') c[i]='\0',printf("%s ",c+i+1);
            printf("%s\n",c+1);
        }
        return 0;
    }

L 今天是第几天
任给三个用一个空格隔开的整数,依次表示年、月、日,说出它是今年的第几天。定义该年的第1天是1月1日。
有多组测试数据.输入的第一行是整数T(1<=T<=200), 表示随后测试数据的组数. 每组测试数据占一行, 由三个分别表示年、月、日的正整数构成. 相邻两个数之间有一个空格.
对应每组测试数据, 输出一行的结果.

提示 一个年份 d 是闰年可以用三元运算符这样表示:d 能被 100 整除 ? d 能被 400 整除 : d 能被 4 整除


    int T,yea,mon,day,cal[13]={0,31,28,31,30,31,30,31,31,30,31,30,31},sum[13];
    inline bool check() { return yea%100==0?yea%400==0:yea%4==0; }
    int main()
    {
        for (register int i=1;i<=12;++i) sum[i]=sum[i-1]+cal[i];
        for(read(T);T;--T)
        {
            read(yea);
            read(mon);
            read(day);
            if(mon>2&&check()) printf("%d\n",sum[mon-1]+day+1);
            else printf("%d\n",sum[mon-1]+day);
        }
        return 0;
    }


后面的题实在太水,懒得写了,以后挑有意思的题写吧。。

©著作权归作者所有

发表评论

正在加载 Emoji