广西大学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;
}