# 每天一道算法题，菜鸟也能成高手！哈哈(2011年10月篇)

1、题目：输入一个正数n，输出所有和为n 连续正数序列。

(思路是付老师提的，我之前都没想到，付老师雄起)

public class continum {
static void find(int num){
int a,sum,j;
for (int i=2;i<num/2;i++)
{
a=num/i;
int k;
for(k=0;k<i;k++)
{
sum=i*(a-i+1)+k*i+i*(i-1)/2;
if(sum==num&&(a-i+1)>0)
{
System.out.print(sum+"=");
for(j=k;j<i+k;j++)
{
int m=a-i+j+1;
if(m>0)
{
System.out.print(m+"+");
}
else break;
}
}
}
System.out.println();
}
}
public static void main(String[] args){
find(25);//找25
}
}


2、编程实现两个正整数的除法，当然不能用除法操作符。

// return x/y.
int div(const int x, const int y) {
....
}

public class div {
static void div(int x,int y)
{
int i;
for (i=1;i<=x;)
{
if (x-i*y>0 && x-i*y<y)
{
System.out.print(x+"/"+y+"="+i);
break;
}
else i++;
}
}
public static void main(String[]args)
{
div(12,8);
}

}


3、写程序找出二叉树的深度。

一个树的深度等于max（左子树深度，右子树深度）+1。可以使用递归实现。

struct Node {
Node* left;
Node* right;
};

int GetDepth(Node* root) {
if (NULL == root) {
return 0;
}
int left_depth = GetDepth(root->left);
int right_depth = GetDepth(root->right);
return left_depth > right_depth ? left_depth + 1 : right_depth + 1;
}


4 、（峰哥给的acm题）

Problem Description
A checksum is an algorithm that scans a packet of data and returns a single number. The idea is that if the packet is changed, the checksum will also change, so checksums are often used for detecting transmission errors, validating document contents, and in many other situations where it is necessary to detect undesirable changes in data.

For this problem, you will implement a checksum algorithm called Quicksum. A Quicksum packet allows only uppercase letters and spaces. It always begins and ends with an uppercase letter. Otherwise, spaces and letters can occur in any combination, including consecutive spaces.

A Quicksum is the sum of the products of each character's position in the packet times the character's value. A space has a value of zero, while letters have a value equal to their position in the alphabet. So, A=1, B=2, etc., through Z=26. Here are example Quicksum calculations for the packets "ACM" and "MID CENTRAL":

ACM: 1*1 + 2*3 + 3*13 = 46MID CENTRAL: 1*13 + 2*9 + 3*4 + 4*0 + 5*3 + 6*5 + 7*14 + 8*20 + 9*18 + 10*1 + 11*12 = 650

Input
The input consists of one or more packets followed by a line containing only # that signals the end of the input. Each packet is on a line by itself, does not begin or end with a space, and contains from 1 to 255 characters.

Output
For each packet, output its Quicksum on a separate line in the output.

Sample Input
ACM
MID CENTRAL
REGIONAL PROGRAMMING CONTEST
ACN
A C M
ABC
BBC
#

Sample Output
46
650
4690
49
75
14
15

#include <iostream>
#include <math.h>
#include <string>
#include <stdio.h>
using namespace std;

void main()
{
int s[255];//={-2};
for(int m=0;m<255;m++){s[m]=-2;}//初始化数组
int i=0;
char ch;
//cin>>ch;
scanf("%c",&ch);
while(ch != '#')
{
if(ch==' ')
{
s[i]=0;//空格存储为0
}
else if(int(ch)=='\n')
{
s[i]=-1;//回车存储为-1
}
else if(ch>='A' && ch<='Z')
{
s[i]=ch-'A'+1;//字母存储为对应的数字
}
else
{
break;
cout<<"Wrong num"<<endl;
}
i++;
scanf("%c",&ch);
//	cin>>ch;
}
int j=0;
//	for(m=0;m<20;m++){cout<<s[m]<<endl;}
while(s[j]!=-2)
{
int k=1;
int sum=0;
while(s[j]!=-1 && s[j]!=-2)
{
sum=sum+s[j]*k;
k++;
j++;
}
j++;
cout<<"sum="<<sum<<endl;
}

}

5、输入为一个很长的字符串，字符之间是分段连续的（如bcdefbcdabbc）,求里面最长的连续子序列，没有返回NULL,有则返回首地址及长度。（传说中腾讯面试题）

#include <stdio.h>
void main()
{
char s[255];
int count[255];
for(int m=0;m<255;m++){count[m]=-1;}
char ch;
int i=0,j=0;
scanf("%c",&ch);
if(ch!='#')
{
s[i]=ch;
count[j]=i;
scanf("%c",&ch);
while(ch!='#')
{
if(ch>=s[i])
{
i++;
s[i]=ch;
scanf("%c",&ch);
}
else
{
j++;
count[j]=i;
i++;
s[i]=ch;
j++;
count[j]=i;
scanf("%c",&ch);
}
}
count[j+1]=i;
}
else {printf("Wrong!");}
//for(m=0;m<10;m++){printf("%d\t",count[m]);}
int k=0,max=0,a=0;
j=0;
while(count[j]!=-1)
{
a=count[j+1]-count[j];
if(a>max)
{
max=a;k=j;//printf("k=%d,max=%d",k,max);
}
j=j+2;
}
//	printf("k=%d,max=%d",k,max);
printf("连续的串为：");
for(j=count[k];j<=max+count[k];j++)
{
printf("%c\n",s[j]);
}
}

6、判断一个自然数是否是某个数的平方。当然不能使用开方运算。

(n+1)^2
=n^2 + 2n + 1，
= ...
= 1 + (2*1 + 1) + (2*2 + 1) + ... + (2*n + 1)

第三种解法比较好，我用代码实现了一下：

public class dermin_seq {
static void dermin_seq(int N)
{
int i,count=N;
int j=1;
for(i=1;;)
{
count=count-i;
if(count==0)
{
System.out.println(N+"="+j+"*"+j);break;
}
else if(count > 0)
{
i=i+2;j=j+1;
}
else
{
System.out.println(N+"不是自然数的平方");break;
}
}
}
public static void main(String[]args)
{
dermin_seq(25);
dermin_seq(36);
dermin_seq(33);
}
}


7、【网易2012校招】编程题。编写代码把16进制表示的串转换为3进制表示的串。例如x=”5”，则返回：”12”；又例如：x=”F”，则返回”120”。

public class sixteentothree {
/*10进制转为3进制*/
public static void TentoThree(int N){
int j=0,R,m,i=N;
int[] A={-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1};
while(i>0){
A[j]=i%3;//取余数
j++;
i=i/3;//取商
}
for(m=A.length-1;m>=0;m--){if(A[m]>=0)System.out.print(A[m]);}
System.out.println();
}
/*16进制转为10进制*/
public static int SixteenToTen(char[] S){
int M,i,j=0;
int SUM=0;
for(i=S.length-1;i>=0;i--){
if(S[i]>='A' && S[i]<='F')
{
M=S[i]-55;
//System.out.println(M);
SUM=(int) (SUM+M*Math.pow(16,j));//pow(x,y)：x的y次方
//System.out.println(SUM);
j++;
}
else if(S[i]>='0' && S[i]<='9')
{
M=S[i]-48;
//System.out.println(M);
SUM=(int) (SUM+M*Math.pow(16,j));
//System.out.println(SUM);
j++;
}
else {
return -1;
}
}
//System.out.println(SUM);
return SUM;
}
public static void main(String[] args){
//TentoThree(27);
char[] S={'F','1','A','F'};
//System.out.println(SixteenToThree(S));
//TentoThree(431);
TentoThree(SixteenToTen(S));
}

}

8、【有道2012校招】

-1 3 1 -2 4 1

-1
-1 3 1 -2
1
1 -2

#include<stdio.h>
#include<math.h>
const int N=6;
void main()
{
int B[N]={-1,3,1,-2,4,1};
int a[N][N];
int i,j,k;
for(k=0;k<N;k++){a[k][k]=B[k];}//斜对角赋值
for(i=0;i<N;i++)
{
for(j=i+1;j<N;j++)
{
a[i][j]=a[i][j-1]+B[j];
}
}
int min=abs(a[0][0]);
for(i=0;i<N;i++)//找最小值
{
for(j=i;j<N;j++)
{
if(abs(a[i][j])<min)
{
min=abs(a[i][j]);
}
}
}
for(i=0;i<N;i++)//输出
{
for(j=i;j<N;j++)
{
if(abs(a[i][j])==min)//扫描数组，找出与最小值相等的元素
{
for(k=i;k<=j;k++)
{
printf("%d ",B[k]);
}
printf("\n");
}

}
}
}

• 本文已收录于以下专栏：

举报原因： 您举报文章：每天一道算法题，菜鸟也能成高手！哈哈(2011年10月篇) 色情 政治 抄袭 广告 招聘 骂人 其他 (最多只允许输入30个字)