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;
}