广西大学计算机系上机题库代码一览20级

广西大学2020级计算机系题库代码解析与参考答案


前言

提示:代码分为极简版本和标准化版本,并不是说极简会好背或者标准化版本就繁琐,各有各的优势,贴两副代码仅供各位参考学习,预祝各位程设考出好成绩


一、判断升序

主要思路是前者与后者相比大小,符合条件即输出YES^NO;

极简版

#include<stdio.h>
int x[200005] = {},i=1,flag=1;
int main()
{
	scanf("%d", &x[0]);
	while (scanf("%d", &x[i]) != EOF) (x[i - 1] <= x[i])?i++:(flag=0);
	flag?printf("YES"):printf("NO");
}//极简版本
#include<stdio.h>
int x,n=1,f=1;
int main(){
	for(f=1,scanf("%d",&x);~scanf("%d",&n);x=n) f&=x<=n;
    puts(f?"YES":"NO");
}

标准版

#include<stdio.h>
int main(void)
{
	long long  a[50004] = {};
	int i = 1;
	int flag = 0;
	a[0] = -0x3f3f3f3f;//最小值
	while (scanf("%d", &a[i])!=EOF) {
		if (a[i] >= a[i - 1]){//这一步是用来和前一项比较		
            i++;
     
        }
		else flag = 1;
      
	}
	if(flag)
	printf("NO\n");
	else	printf("YES\n");
	return 0;
}//工业化代码

二、小西的排序

主要思路是利用结构体去捆绑排序,排序的有效手段是快速排序和冒泡排序;

极简版(快速排序)

代码如下(示例):

#include<stdio.h>
#include<stdlib.h>
typedef struct node {char x[20];double y;}T;
T x[2005] = {};
//快速排序的重载函数,用于比较大小
int cmp(const void* a, const void* b)
{
	return (*(T*)a).y > (*(T*)b).y ;
}
int main()
{
	int n;
	while (scanf("%d", &n) != EOF) {
		for (int i = 0; i < n; i++) scanf("%s %lf", &x[i].x, &x[i].y);
		qsort(x, n, sizeof(T), cmp);//快速排序,直接重载装上就排好了
		for (int i = 0; i < n; i++)	printf("%s ", x[i].x);
		printf("\n");
	}
}

标准版(冒泡排序)

代码如下(示例):

#include<stdio.h>
int n;
struct {char s[21];double hi;}bd[100],t;
int main(){
	while(~scanf("%d",&n)){
    	for(int i=0;i<n;i++) scanf("%s %lf",&bd[i].s,&bd[i].hi);
    	for(int i=0;i<n;i++) for(int j=1;j<n;j++) 
          	if(bd[j].hi<bd[j-1].hi) t=bd[j-1],bd[j-1]=bd[j],bd[j]=t;
      	for(int i=0;i<n;i++) printf("%s ",bd[i].s);
      	puts("");
    }
}

三、小西的数(动词)数(名词)

就每个位的数字都统计一遍得了,数据不大,肯定能过。

暴力思维极简

#include<stdio.h>
#define ll long long 
ll ans = 0,n,flag;
int  x[2005] = {};
int main()
{
	while (scanf("%d%d", &n,&flag)!=EOF ){
		ans = 0;
		for (int i = 1; i <= n; i++) {
			int tmp = i;
			while (tmp) {
				if (tmp%10 == flag) ans++;
				tmp /= 10;
			}
		}
		printf("%lld\n", ans);
	}
}

纯思维高效解

不建议在考试的时候使用本代码,思维挺大的

#include<stdio.h>
int main(){
    int n,x,m=1,ans=0;
    while(scanf("%d%d",&n,&x)!=EOF){
      ans=0,m=1;
    while(m<=n){
        int a=n/(m*10),b=n/m%10,c=n%m; //a,b,c为n的三部分,求哪一位x的个数,b就为那一位数,a为b左边的数,c为b右边的数,如求1~728中十位7的个数,则a=7,b=2,c=8
        if(x){
            if(b>x) ans+=(a+1)*m; //如果b>x,说明有(a+1)*m个x(如求1~728中个位7的个数,则为(72+1)*1=73)
            if(b==x) ans+=a*m+c+1; //如果b=x,说明有a*m+c+1个x(如求1~728中百位7的个数,则为0*100+28+1=29)
            if(b<x) ans+=a*m; //如果b<x,说明有a*m个x(如求1~728中十位7的个数,则为7*10个)
        }
        else{ //x=0的情况和x!=0的情况有所不同
            if(b) ans+=a*m;
            else ans+=(a-1)*m+c+1;
        }
        m*=10;
    }
    printf("%d\n",ans);
  }
}

四、小西买西瓜

主体思路就是能买五就买5,不行就买3,输出即可。
其他思路主要是动态规划思想,利用前面的结果去影响后面的进程。不推荐考试使用

标准代码,动态规划思想

#include<string.h>
#include<stdlib.h>
#define ll long long 
#define max(a,b) a>b?a:b;
ll ans = 0;

int  x[2005] = {};
int main()
{
	int n;
	int flag;
	while (scanf("%d", &n) != EOF) {
		ans = 0;
		int dp[10000] = {};
		dp[1] = 1;
		dp[2] = 2;
		dp[3] = 4;
		dp[4] = 5;
		for (int i = 5; i <= n; i++) {
			dp[i] = max(dp[i - 3] + 4, dp[i - 5] + 7);
		}
		printf("%d\n", dp[n]);
	}
}

极简版数学代码

#include<stdio.h>
int main(void)
{
	long long int a,sum;
	while(scanf("%lld",&a)!=EOF){
		sum=a+a/5*2+a%5/3;
		printf("%lld\n",sum);
	}return 0;
}

五、通话记录

代码的主要思想还是数据结构的栈,存进去,然后存出来,只不过是利用了数组进行了简单的模拟

标准代码

#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#define ll long long 
#define max(a,b) a>b?a:b;
ll ans = 0;
typedef struct x {
	int a;
	ll b;
} T;
T  x[2005] = {};
ll z[5][2000] = {0};
int main()
{
	int n;
	int flag=10;
	int i = 0;
	int j = 0, k = 0, l = 0;
	while (scanf("%d%lld", &x[i].a,&x[i].b) != EOF) {
		if(x[i].a==0)
		z[x[i].a][j++] = x[i].b;
		else if (x[i].a == 1)
			z[x[i].a][k++] = x[i].b;
		else if (x[i].a == 2)
			z[x[i].a][l++] = x[i].b;
		
			
	}
	while (flag--) {
		--j >= 0 ? printf("%lld ", z[0][j]) :printf("0 ") ;
		--k >= 0 ? printf("%lld ", z[1][k]) : printf("0 ");
		--l >= 0 ? printf("%lld", z[2][l]) : printf("0");
		printf("\n");
	}
}
接下来是非常牛逼的神仙代码

极简代码(神仙优化)

#include<stdio.h>
long long s[3][10]={},q[3]={},i;
int main(){
	while(~scanf("%lld",&i)) 
		scanf("%lld",&s[i][q[i]++%10]);//mod10只取前十个数据,遵守先进后出原则
	for(int i=0;i<10;i++) 
		for(int j=0;j<3;j++) 
			printf("%lld",s[j][(--q[j]+20)%10]),//模拟栈出,20用来保护数组不会爆
			putchar(j==2?'\n':' ');//细节上一句是,因此下一句在紧跟上一句直接执行,判定是否空格或回车
}

六、基础练习 字符串对比

其实挺短的了,就先贴出来给大家做一个参考,有疑问可以下面评论。

标准代码实现

#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#define ll long long 
ll ans = 2;
char x[1000] = {};
char y[1000] = {};
int main()
{
	scanf("%s%s", &x, &y);
	ll a,  b = 0;
	a = strlen(x);
	b = strlen(y);
	if (a == b) {
		for (int i = 0; i < a; i++) {
			if (x[i] != y[i]) {
				if (x[i] == y[i] - 'A' + 'a' || x[i] - 'A' + 'a' == y[i]) ans = 3;
				else {
					ans = 4;
					break;
				}
			}
		}
	}
	else ans = 1;
	printf("%lld", ans);
}

七、排列问题

废话也不多说,标准版的代码注释详尽,基本上也可以看懂了

标准代码

#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
#include<stdlib.h>
int N, K, count=0, key=1;
int a[10][10] = {}, num[10] = {};
//cmp是经典的qsort重载部分,用于定义排序的比较内容 ,比较效果。这里定义的是从小到大排序
int cmp(const void* a, const void* b) {
    return(*(int*)a > * (int*)b);
}
//dfs,同样是全排列
void arrange(int r)
{
    //出现了第count个排列,那么count++,也就是有一组排列排好了
    if (r == N) {
        count++;
    }
    //如果这组排列满足了第k组,那么就把他输出
    if (count == K) {
        for (int i = 0; i < N; i++) {
            printf("%d ", num[i]);
        }
        printf("\n");
        key = 0;//宣布数组输出结束
    }
    //全排列本体,可以用手模拟自己排列的过程来推导
    for (int i = r; i < N; i++) {
     
        //将后面的n-r个数字进行从小到大排序,实现从小到大全排列
        qsort(num + r, N - r, sizeof(int), cmp);
      
        int t;
        t = num[i];
        num[i] = num[r];
        num[r] = t;//新的最小值放最前面,原来的最小值和新值交换位置
        
        if (r == 0) arrange(r + 1);//判定条件,然后dfs
        else if( a[num[r - 1]][num[r]] != 0)  arrange(r + 1);
        if (key == 0)     return;//发现结束了,那就结束了
    }
}
int main()
{
    scanf("%d%d", &N, &K);
    for (int i = 0; i < N; i++) {
        for (int j = 0; j < N; j++)      scanf("%d", &a[i][j]);//收集矩阵条件
               num[i] = i;//初始化数组
    }
    arrange(0);
    return 0;
}

简易版搜索

#include<stdio.h>
int vis[12],fob[12];
int stir[12][12],ans[12];
int n,k,ki=0;
void print(){
  for(int i=0;i<n;i++)  printf("%d%c",ans[i],i==n-1?'\n':' ');
}
void dfs(int len){
  if(len==n) {
    ki++;
    if(ki==k) print();
  }
  for(int i=0;i<n;i++) 
    if(vis[i]==0){
      if(len>0&&stir[ans[len-1]][i]==0) continue;
      ans[len]=i;
      vis[i]=1;
      dfs(len+1);
      vis[i]=0;
    }
}
int main() {
  scanf("%d%d",&n,&k);
  for(int i=0;i<n;i++) for(int j=0;j<n;j++)  scanf("%d",&stir[i][j]);
  dfs(0);
}

八、组合问题

画图理解组合到底如何进行,利用递归完成若干个循环的深入。

标准代码实现

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
long long n, r, arr[50000] = {};

void func(long long step, long long t) {
	if (step == r + 1)
	{
		for (int j = 1; j <= r; j++)
			printf("%lld" , arr[j]);
		printf("\n");
		return;
	}
	for (long long i = t + 1; i <= n - r + step; i++)
	{
		arr[step] = i;
		func(step + 1, i);
	}
	return;
}
int main()
{
	long long k;
	scanf("%lld", &k);
	while (k--)
	{
		scanf("%lld %lld", &n, &r);
		func(1, 0);
	}
	return 0;
}

九、小西与数据结构

这题我考虑直接进行数据模拟,代码也挺清晰好懂。

标准代码

#include<stdio.h>
int main()
{
	int m,n,t,i,j,x;
	long long int s[50000]={},a,b,c,sum=0;
	while(scanf("%d%d",&n,&m)!=EOF){
		i=1;
	while(n--){
		scanf("%lld",&s[i]);
		i++;
	}
	for(j=0;j<m;j++){
		scanf("%d",&t);
		if(t==1){
		scanf("%lld%lld",&a,&b);
		for(int tmp=a;tmp<=b;tmp++){
         sum+=s[tmp];
        }
		printf("%lld\n",sum);
		sum=0;
		}
		else if(t==2){
			scanf("%lld%lld%lld",&a,&b,&c);
			for(x=a;x<=b;x++){
				s[x]+=c;
			}
		}
	}
}
	return 0;
}

十、进制转换

这题的核心是如何装下一个巨大的数字,我的思路是直接全部读成字符串,通过模拟的方式把字符串当成数字进行进制转换。

标准代码

#include<stdio.h> 
#include<string.h>
int main()
{
    char a[1000],a1[1000];
    long b;
    int i, j, n, mod, mod1;
    while (scanf("%s", a)!=EOF)
    {
        n = strlen(a);
        b = 0;
        i = 0;
        while (i != n)
        {
            mod = 0;
            mod1 = 0;
            a1[b++] = (a[n - 1] - '0') % 2 + '0';
            for (j = i; j < n; j++)
            {
                mod = (mod1 * 10 + a[j] - '0') % 2;		//余数 
                a[j] = (mod1 * 10 + a[j] - '0') / 2 + '0';	//商 
                mod1 = mod; //余数 
            }
            if (a[i] == '0')
                i++;
        }
        for (b--; b >= 0; b--)
        {
            printf("%c", a1[b]);
        }
        printf("\n");
    }
	return 0;
}
  • 30
    点赞
  • 50
    收藏
    觉得还不错? 一键收藏
  • 6
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值