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\n",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("\n");
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\n",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\n",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\n",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\n",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\n",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\n",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\n",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\n");
42     else printf("NO\n");
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\n",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\n",solve());
27     else printf("-1\n");
28     return 0;
29 }

 

posted @ 2018-12-01 12:48  starry_sky  阅读(1272)  评论(0编辑  收藏  举报