果壳OJ写题记录1

果壳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 1a2311,1b.length2000,0b[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 1n,m105)
— 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 231x2311)
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;
}

遇到的问题

  1. 大数问题
    大数指的是超过了计算机常用数据类型范围的数,大数的加减乘除不能直接被处理,常用的方法是按位处理。解题过程中参考了几篇博文如下:

大数乘法C语言
c语言之大数基本运算

  1. 快速幂算法
    很容易想到快速幂算法,本质就是平方递增基底,在每次递增时需要考虑指数奇偶的影响。主要参考了下面这篇博文,讲的非常清楚:
    C语言实现快速幂
  2. C语言指针的使用
    模模糊糊,懵懵懂懂中。。。。搞明白再来说。
  3. 参数传递
    好久没写ACM模式,导致参数传递都忘了,新手还是得常写代码练练手。
  4. 二分查找
    二分查找的边界问题(应遵循循环不变量原则!!可以参考二分查找边界规则
    二分查找的目的!!
  5. 还有好多想想再写,革命正在路上,同志仍需努力!!!!
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值