果壳OJ写题记录1
最近上算法课的编程作业要在UCAS的OJ上完成,两道题目都不难,但是果壳OJ是真滴让人抓狂,大家都被折磨得不轻。(幸好我是用C写的,顺利完成,记录代码及编写程序中遇到的新老问题)
题目1(快速幂)
计算 p o w ( a , b ) % p pow(a,b)\%p pow(a,b)%p, 其中 1 ≤ a ≤ 2 31 − 1 , 1 ≤ b . l e n g t h ≤ 2000 , 0 ≤ b [ i ] ≤ 9 1\le a \le 2^{31} - 1,1 \le b.length \le 2000,\, 0 \le b[i] \le 9 1≤a≤231−1,1≤b.length≤2000,0≤b[i]≤9
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<math.h>
#define N 4001//b.length≤2000,故需要定义40001长的字符数组储存b
int fun(long long a, int* b, int p,int len)
{
int ans=1;
if((len==1&&b[0]==0)||a==1) return ans;
int Len=len;
while(len>0)
{
if(b[Len-1]%2==1) ans =((ans*a)%p)%p;//奇数的情况
a=(a*a)%p;
numDevision(b,Len); //十进制大数除法
if(b[Len-len]==0) len--;
}
return ans;
}
void numDevision(int *b ,int len){
int i,label=0,div=0,num=0;
for(i=0;i<len;i++){
if(label==1) num=b[i]+10;
else num=b[i];
label=num%2;
div=num/2;
b[i]=div;
}
}
int main()
{
long long a;
int p=1337,flag=0;
int len,i;
char b[N];
scanf("%lld",&a);
scanf("\n");//输入两行之间有空格!!!好奇怪
scanf("%s",b);
len=strlen(b);
int *c=(int*)malloc((len/2)*sizeof(int*));
for(i=1;i<len;i+=2)
{
c[flag++]=b[i]-'0';
}
int result=fun(a,c,p,len/2);
free(c);
c=NULL;
printf("%d",result);
return 0;
}
题目2(数组中找数)
Given an array of integers numbers sorted in ascending order, find the starting and ending position of several given target values. If a target is not found in the array, return [-1, -1]. You must write an algorithm with
O
(
l
o
g
n
)
O(logn)
O(logn)runtime complexity for each given target.
Input
Line 1: two integers n and m (
1
≤
n
,
m
≤
1
0
5
1\leq n,m\leq 10^5
1≤n,m≤105)
— the length of array and the number of targets.
Line 2: the all elements in array and split by spaces(for each element
−
2
31
≤
x
≤
2
31
−
1
-2^{31}\leq x\leq 2^{31}-1
−231≤x≤231−1)
Line 3~Line m+2: targets
Output
For each target ,print one line containing the starting and ending position split by spaces.
#include<stdio.h>
#include<malloc.h>
int dichotomousSearch(long *scope,long len,long *nums,long currentFind){
long key=0,left=0;
long right=len-1;
while(left<right){
key=(left+right)/2;
if(nums[key]<currentFind) left=key+1;
else right=key;
}
if(nums[left]==currentFind) scope[0]=left;
right=len-1;
while(left<right){
key=(left+right+1)/2;
if(nums[key]>currentFind) right=key-1;
else left=key;
}
if(nums[right]==currentFind) scope[1]=right;
return 0;
}
int main(){
long n,m,i;
long currentFind;
scanf("%ld %ld\n",&n,&m);
long *nums=(long*)malloc(n*sizeof(long*));
long *targets=(long*)malloc(m*sizeof(long*));
for(i=0;i<n;i++){
scanf("%ld",&nums[i]);
}
for(i=0;i<m;i++){
scanf("%ld",&targets[i]);
}
for(i=0;i<m;i++){
// printf("\n当前寻找%ld\n",targets[i]);
long scope[2]={-1,-1};
// int result[2]={-1 -1};
currentFind=targets[i];
dichotomousSearch(scope,n,nums,currentFind);
printf("%ld %ld\n",scope[0],scope[1]);
}
free(nums);
nums=NULL;
free(targets);
targets=NULL;
return 0;
}
遇到的问题
- 大数问题
大数指的是超过了计算机常用数据类型范围的数,大数的加减乘除不能直接被处理,常用的方法是按位处理。解题过程中参考了几篇博文如下: