zoukankan      html  css  js  c++  java
  • 2018年江西理工大学C语言竞赛初级组第一、二套题解

    比赛时发现好多人喜欢多输出些东西,这反而会答案错误。

    题目说输出什么就输出什么,不要多输出任意东西就行。

    第一套:

    A  整数序列中两个相邻的数,如果后面的数小于前面的数,则称这两个数值构成了一个逆序对。例如,整数序列10,4,16,8,21,18,9中包含了4个逆序对。从键盘上输入n(n≤1000)个由空格分隔的整数,编程输出其中包含的逆序对的数量。

    签到题。

     1 #include <stdio.h>
     2 const int N = 1010;
     3 int a[N];
     4 int main() {
     5     int n, ans = 0;
     6     scanf("%d", &n);
     7     for(int i = 1; i <= n; i ++) scanf("%d",&a[i]);
     8     for(int i = 1; i < n; i ++) if(a[i] > a[i+1]) ans++;
     9     printf("%d
    ",ans);
    10     return 0;
    11 }

    B 最近小S不高兴了,所以她就想画圈圈,有大有小的。而现在她想让你也画圈圈了^_^。

    大小为3的圈圈是,大小为4的圈圈是,大小为5的圈圈是,依次类推。

    接着送分题

     1 #include <stdio.h>
     2 
     3 int main() {
     4     int n;
     5     scanf("%d", &n);
     6     for(int i = 1; i <= n; i ++) {
     7         for(int j = 1; j <= n; j ++) {
     8             if((i == 1 || i == n) && (j == 1 || j == n)) printf("*");
     9             else if(i == 1 || i == n || j == 1 || j == n) printf("#");
    10             else printf("*");
    11         }
    12         printf("
    ");
    13     }
    14     return 0;
    15 }

    C 小明现在有x元,现在想买一件y(y ≤ x)元的物品,商店里有五种货币,100元、20元、10元、5元、1元无限张,服务员会以最小的数量找零钱。问小明用x元买了一件y元的物品后找了多少张零钱。

    第一套和第二套都有这题,不过第一套的是没有50元,第二套的是没有100元。

    贪心,每次找最大的货币,这样就能使的零钱数量最少。

     1 #include <stdio.h>
     2 
     3 int main() {
     4     int x, y, ans = 0;
     5     scanf("%d%d", &x, &y);
     6     x -= y;
     7     ans += x/100; x %= 100;
     8     ans += x/20; x %= 20;
     9     ans += x/10; x %= 10;
    10     ans += x/5; x %= 5;
    11     ans += x/1;
    12     printf("%d
    ",ans);
    13     return 0;
    14 }

    D 现在的编程越来越多了,比如C、C++、Java、Python、C#、PHP等等。现在给定n种编程语言,每种语言还会给一个[1,n]之间的随机值,保证不重复。现在让你按随机值从小到大排序,然后输出对应的语言。

    输入:

    第一行输入一个整数n(1≤ n ≤ 20)

    接下来n行,每行有一个字符串和一个随机值,字符串表示一种语言,长度不超过20.随机值范围为[1,n]

    用结构体储存编程语言的名字和随机值。

    n最大才20,随便用种排序就能过。

     1 #include <stdio.h>
     2 struct Nod{
     3     char s[22];
     4     int id;
     5 }e[22], tmp;
     6 
     7 int main() {
     8     int n;
     9     scanf("%d",&n);
    10     for(int i = 1; i <= n; i ++) {
    11         scanf("%s%d",e[i].s,&e[i].id);
    12     }
    13     for(int i = 1; i <= n; i ++) {
    14         for(int j = i+1; j <= n; j ++) {
    15             if(e[i].id > e[j].id) {
    16                 tmp = e[i];
    17                 e[i] = e[j];
    18                 e[j] = tmp;
    19             }
    20         }
    21     }
    22     for(int i = 1; i <= n; i ++) printf("%s
    ",e[i].s);
    23     return 0;
    24 }

    E 有一个四边形,现在需要求它的面积。

    需要注意的是有凸凹边形。

    将四边形分成两个三角形,计算两个三角形面积的和就是答案。

    但由于用凹边形,将四边形分成两个三角形时,有两种答案。在纸上画下这两个分法。其实不难得出面积最小的那个就是四边形的正确面积。

     1 #include <stdio.h>
     2 #include <math.h>
     3 
     4 double min(double x, double y) { return x>y?y:x;}
     5 double x[4], y[4];
     6 
     7 double dist(double x1, double y1, double x2, double y2) {
     8     return sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2));
     9 }
    10 double getArea(double a, double b, double c) {
    11     double p = (a+b+c)/2.0;
    12     return sqrt(p*(p-a)*(p-b)*(p-c));
    13 }
    14 int main() {
    15     for(int i = 0; i < 4; i ++) scanf("%lf%lf",&x[i], &y[i]);
    16     double l1, l2, l3, l4, l5, l6;
    17     l1 = dist(x[0],y[0],x[1],y[1]);
    18     l2 = dist(x[1],y[1],x[2],y[2]);
    19     l3 = dist(x[2],y[2],x[3],y[3]);
    20     l4 = dist(x[3],y[3],x[0],y[0]);
    21     l5 = dist(x[0],y[0],x[2],y[2]);
    22     l6 = dist(x[1],y[1],x[3],y[3]);
    23     double area1 = getArea(l1,l2,l5)+getArea(l3,l4,l5);
    24     double area2 = getArea(l1,l4,l6)+getArea(l2,l3,l6);
    25     printf("%.3lf
    ",min(area1,area2));
    26     return 0;
    27 }

    F 给定一个区间[l, r],从l至r之间的所有数依次转换成16进制然后连在一起,接着再转换成10进制,最后再对15取模。

    将区间内的数字拼接成16进制,其实16中的每一位都可以转化成a*16^b的其实。而16^b % 15 == 1  。这样就是对区间内的数求和在对15取模。

    以样例为例,703710 = 10*16^4+11*10^3+12*16^2+13*16^1+14*10^0。16^4%15==1  10^3%15==1 10^2%15==1 10^1%15==1 10^0%15==1

    所以答案就是(10+11+12+13+14)%15 == 0 

     1 #include <stdio.h>
     2 
     3 int main() {
     4     int l, r, ans = 0;
     5     scanf("%d%d",&l,&r);
     6     for(int i = l; i <= r; i ++) {
     7         ans = (ans+i)%15;
     8     }
     9     printf("%d
    ",ans);
    10     return 0;
    11 }

    上面的复杂度高了。 由于%15  所以每16个数就一个循环。(1+14)%15=0 (2+13)%15=0...(7+8)%15=0,这样那些循环的都是0,只要计算那些没有循环的就行了。这样循环最多才15次。

     1 #include <stdio.h>
     2 
     3 int main() {
     4     int l, r, ans = 0;
     5     scanf("%d%d", &l, &r);
     6     r = r-(r-l)/15*15;
     7     for(int i = l; i <= r; i ++) {
     8         ans = (ans+i)%15;
     9     }
    10     printf("%d
    ",ans);
    11     return 0;
    12 }

    第二套

    A 和第一套一样。

    B 又一道签到题。判断下位置就行了。

     1 #include <stdio.h>
     2 
     3 char s[4][16];
     4 
     5 int main() {
     6     char ch;
     7     for(int i = 0; i < 4; i ++) scanf("%s",s[i]);
     8     for(int i = 0; i < 3; i ++) {
     9         for(int j = 0; s[i][j]; j ++) {
    10             if(s[i][j] == s[3][0]) {
    11                 printf("%d %d
    ",i+1,j+1);
    12             }
    13         }
    14     }
    15     return 0;
    16 }

    C 和第一套的C题解题思路一样。

     1 #include <stdio.h>
     2 
     3 int main() {
     4     int x, y, ans = 0;
     5     scanf("%d%d", &x, &y);
     6     x -= y;
     7     ans += x/50; x %= 50;
     8     ans += x/20; x %= 20;
     9     ans += x/10; x %= 10;
    10     ans += x/5; x %= 5;
    11     ans += x/1;
    12     printf("%d
    ",ans);
    13     return 0;
    14 }

    D 数独是源自18世纪瑞士的一种数学游戏。是一种运用纸、笔进行演算的逻辑游戏。玩家需要根据9×9盘面上的已知数字,推理出所有剩余空格的数字,并满足每一行、每一列、每一个粗线宫(3×3)内的数字均含1-9,不重复。当然,肯定不会让你用程序完成没填好的数独的。现在给你一个9×9填满了数的格子,想让你检查一下是不是符合数独的定义。比如下图是符合数独的定义的。

    判断下每9列,每9行和每9个粗线是否是1-9都出现了一次就行。

     1 #include <stdio.h>
     2 #include <string.h>
     3 char s[10][10];
     4 bool vis[10];
     5 bool ok1(int x, int y) {
     6     memset(vis, 0, sizeof(vis));
     7     for(int i = x; i < x+3; i ++) {
     8         for(int j = y; j < y+3; j ++) {
     9             if(vis[s[i][j]-'0']) return false;
    10             vis[s[i][j]-'0'] = 1;
    11         }
    12     }
    13     return true;
    14 }
    15 bool ok2(int pos, int flag) {
    16     memset(vis, 0, sizeof(vis));
    17     if(flag == 1) {
    18         for(int i = 1; i <= 9; i ++) {
    19             if(vis[s[pos][i]-'0']) return false;
    20             vis[s[pos][i]-'0'] = 1;
    21         }
    22     } else {
    23         for(int i = 1; i <= 9; i ++) {
    24             if(vis[s[i][pos]-'0']) return false;
    25             vis[s[i][pos]-'0'] = 1;
    26         }
    27     }
    28     return true;
    29 }
    30 int main() {
    31     bool flag = true;
    32     for(int i = 1; i <= 9; i ++) scanf("%s",s[i]+1);
    33     for(int i = 1; i <= 9; i ++) {
    34         if(!ok2(i,1) || !ok2(i,0)) flag = false;
    35     }
    36     for(int i = 1; i <= 7; i += 3) {
    37         for(int j = 1; j <= 7; j += 3) {
    38             if(!ok1(i,j)) flag = false;
    39         }
    40     }
    41     if(flag) printf("YES
    ");
    42     else printf("NO
    ");
    43     return 0;
    44 }

    E 现在有n个棒棒糖,对于每个棒棒糖都有两个数Ai,Bi,Ai表示棒棒糖的体积,Bi表示棒棒糖放入水中每秒融化的体积。然后有m个装满水的杯子,每个杯子有且仅能放一个棒棒糖,放完一个棒棒糖后就不能再放其它棒棒糖了,在第0s时就应该将选择的棒棒糖全放在杯子里。问怎么选择棒棒糖使的第s秒到第t秒中间(包括s和t)融化的棒棒糖体积之和最大。

    先计算每根棒棒糖在[s,t]间能融化的棒棒糖体积,按从大到小排下序,去前min(n,m)个体积最大的和就是答案了。

     1 #include <stdio.h>
     2 #define ll long long
     3 
     4 ll res[1010];
     5 int min(int x, int y) {return x>y?y:x;}
     6 int max(int x, int y) {return x>y?x:y;}
     7 int main() {
     8     int n, m, s, t, a, b;
     9     scanf("%d%d%d%d",&n, &m, &s, &t);
    10     for(int i = 1; i <= n; i ++) {
    11         scanf("%d%d", &a, &b);
    12         res[i] = min((t-s+1)*b, max(0,a-(s-1)*b));
    13     }
    14     for(int i = 1; i <= n; i ++) {
    15         for(int j = i+1; j <= n; j ++) {
    16             if(res[i] < res[j]) {
    17                 int tmp = res[i];
    18                 res[i] = res[j];
    19                 res[j] = tmp;
    20             }
    21         }
    22     }
    23     ll ans = 0;
    24     for(int i = 1; i <= min(n,m); i ++) ans += res[i];
    25     printf("%lld
    ",ans);
    26     return 0;
    27 }

    F 给定两个整数a和b(保证所有数据不包含前导0),现在你可交换a里面任意两个数字,得到一个新的a,使得a为小于等于b的最大整数,例如给定a:1234,b:5555,得到4321。如果找不到小于等于b的最大a,则输出-1。(输出也必须保证不包含前导0,例如0123是不合法输出)。

    一开始就将a组成最小的数。然后两次循环,让两两之间的数都交换下位置,看否还是小于等于b,如果是的话就留下来,不是的话就换回来。因为一开始就是最小的数(即前面的≤后面的),所以每次交换成功后都会使得数字变大些。

    最后看a是否还是≤b  是的话就输出答案,否则输出-1.

     1 #include <algorithm>
     2 #include <iostream>
     3 #include <string.h>
     4 #include <stdio.h>
     5 #define ll long long
     6 using namespace std;
     7 char s[20];
     8 ll solve() {
     9     ll ans = 0;
    10     for(int i = 0; s[i]; i ++) ans = ans*10+s[i]-'0';
    11     return ans;
    12 }
    13 
    14 int main() {
    15     ll a, b;
    16     scanf("%s%lld", &s, &b);
    17     int len = strlen(s);
    18     sort(s,s+len);
    19     for(int i = 0; i < len; i ++) {
    20         for(int j = i+1; j < len; j ++) {
    21             swap(s[i], s[j]);
    22             if(solve() > b) swap(s[i], s[j]);
    23         }
    24     }
    25     a = solve();
    26     if(a <= b) printf("%lld
    ",solve());
    27     else printf("-1
    ");
    28     return 0;
    29 }
  • 相关阅读:
    IDA Supported Processors
    Hex-Rays Decompiler
    USB ISP(ICSP) Open Programmer < PWM ADC HV PID >
    A SCSI command code -- SIMPLIFIED DIRECT-ACCESS DEVICE (RBC)
    How to match between physical usb device and its drive letter?
    记录一下公司数据库升级的步骤
    Windows2003 SQL2005解决系统Administrator密码不知道的问题
    在SSMS里批量删除表、存储过程等各种对象
    用SQLSERVER里的bcp命令或者bulkinsert命令也可以把dat文件导入数据表
    分享一张SQLSERVER执行流程的图片
  • 原文地址:https://www.cnblogs.com/xingkongyihao/p/10046918.html
Copyright © 2011-2022 走看看