2021-02-28

P1009 [NOIP1998 普及组] 阶乘之和

题目描述
请你编一程序实现两种不同进制之间的数据转换。

输入格式
共三行,第一行是一个正整数,表示需要转换的数的进制n(2≤n≤16)n(2≤n≤16),第二行是一个n进制数,若n>10n>10则用大写字母A-FA−F表示数码10-1510−15,并且该nn进制数对应的十进制的值不超过10000000001000000000,第三行也是一个正整数,表示转换之后的数的进制m(2≤m≤16)m(2≤m≤16)。

输出格式
一个正整数,表示转换之后的mm进制数。

输入输出样例
输入
16
FF
2

输出
11111111

#include<bits/stdc++.h>
int main () {
    
    int n, m, i, sum = 0, time = 1;//sum是用来存放转换成十进制后的数
    char a[30];//输入的数组
    int b[30];//存放每一位转换成数是多少的数组
    int c[30];//转换成m进制后存放的数组
    
    scanf("%d%s\n%d", &n, a, &m);
    for(i = 0; a[i]!='\0'; i ++ )//遍历数组
        if(isdigit(a[i]))//isdigit是判断是不是字符型数组的函数
            b[i] = a[i] - '0';//转换成数
        else//是字母
            b[i] = (a[i] - 'A') + 10;//转换成数,记得 + 10
    
    int len1 = i;//i出来之后就是长度
    for(i = len1 - 1; i >= 0; i -- ) {//倒着算出转换成十进制后是多少
        sum += b[i] * time;//乘以每一位十进制的值是多少
        time *= n;//不要忘记*n哦
    }

    int len2 = 0;//转换成m进制时用来表示下一位放在哪里的指针
    
    while(sum >= 1) {//只要还没除完
        c[len2] = sum % m;
        sum /= m;
        len2 ++ ;
    }
    
    for(int i = len2 - 1; i >= 0; i -- )//倒着输出
        if(c[i] < 10) printf("%d", c[i]);//是数字
        else printf("%c", c[i] - 10 + 'A');//是字母
    return 0;
}


P1177 【模板】快速排序
核心思路: 1.先把输入的转化为10进制数,然后再转化为所需要的进制,将该进制数转化为十进制数需要乘该进制数,再代码中则要逆序转换(说白了就是拿十进制作为中间进制) 2.题目中还有要注意的地方输入的为字符而不是数字时,需要转化数值的大小,用到的 函数isdigit(a) 判断输入的字符串是否为整数 3.转换为十进制 4.转换为所需要的进制n,则需要除n取余法

题目描述
利用快速排序算法将读入的N个数从小到大排序后输出。

快速排序是信息学竞赛的必备算法之一。对于快速排序不是很了解的同学可以自行上网查询相关资料,掌握后独立完成。(C++选手请不要试图使用STL,虽然你可以使用sort一遍过,但是你并没有掌握快速排序算法的精髓。)

输入格式
第11行为一个正整数N,第22行包含N个空格隔开的正整数ai,为你需要进行排序的数,数据保证了Ai不超过1000000000。

输出格式
将给定的N个数从小到大输出,数之间空格隔开,行末换行且无空格。

输入输出样例
输入 #1

5
4 2 4 5 1

输出 #1

1 2 4 4 5

说明/提示
对于20%的数据,有N≤1000;

对于100%的数据,有N≤100000。

刚开始使用普通快排,但是只过了两个,剩下三个TLE超时。然后优化了一下就AC了。


普通快排(超时!):

#include<stdio.h>
int fenge(int a[],int left,int right)
{
    int zhou=a[left];
    while(left<right)
    {
        while(left<right&&a[right]>=zhou)
        {
             right--;
        }
        a[left]=a[right];
        while(left<right&&a[left]<=zhou)
        {
            left++;
        }
        a[right]=a[left];
    }
    a[left]=zhou;
    return left;
}
void qsort(int a[],int left, int right )
{
    if(left<right)
    {
        int zhou=fenge(a,left,right);
        qsort(a,left,zhou-1);
        qsort(a,zhou+1,right);
    }
}
void quick_sort(int a[],int length)
{
    qsort(a,0,length-1);
}
int main()
{
     int n;
     scanf("%d",&n);
     int a[n];
     int i;
     for(i=0;i<n;i++)
     {
         scanf("%d ",&a[i]);
     }
     quick_sort(a,n);

     int l;
     for(l=0;l<n;l++)
        printf("%d ",a[l]);
    return 0;
}

在这里插入图片描述
优化后的快排


思想:对于基本有序的大量数据,如果采用最左端的数作为支点,时间复杂度将退化为O(n^2),所以优化思路就是采用中间位置的数作为支点。

include<bits/stdc++.h>
using namespace std;
int L[100005];

void QSort(int L[], int left, int right)
{
	if (left > right)	return;		//递归跳出条件
	int temp = L[(left + right) / 2];	//采用中间位置的数作为支点
	int i = left, j = right;
	while (i <= j)
	{
		while (L[j] > temp)  j--;	//从右往左,大于支点的数跳过
		while (L[i] < temp)	i++;	//从左往右,小于支点的数跳过
		if (i <= j) {	//交换
			int t = L[i];
			L[i] = L[j];
			L[j] = t;
			i++;
			j--;
		}
	}
	//注意:此时j一定小于i
	QSort(L, left, j);	//递归处理左边的数
	QSort(L, i, right);	//递归处理右边的数
}

int main()
{
	int n;
	cin >> n;
	for (int i = 0; i < n; i++)
		scanf("%d", &L[i]);
	QSort(L, 0, n - 1);
	for (int i = 0; i < n; i++)
		printf("%d ", L[i]);
	return 0;
}

在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值