[Blue Bridge Cup] Real Exam Training 2014 C++A Group Question 4 Shi Fengshou Quick Calculation

Shi Fengshou Quick Calculation

    The revolutionary contribution of the Shi Fengshou speed algorithm is: counting from the high position, predicting the carry. There is no need for nine tables, which completely overturns traditional hand calculations!
    The core basis of quick calculations is: multiplication of one digit by multiple digits.
    Among them, multiplying by 7 is the most complicated, just take it as an example.
    Because 1/7 is a recurring decimal: 0.142857..., if the number of digits exceeds 142857..., it is necessary to enter 1. The
    same is true for 2/7 , 3/7, ... 6/7. Cycle decimals, if the number of digits exceeds n/7, it is necessary to enter
    the program below n to simulate the operation process of multiplying by 7 in the Shi Fengshou speed algorithm.
    The law of the ones place for multiplying by 7 is: multiplying even numbers by 2, and multiplying odd numbers by 2 and adding 5. All only take the ones place.
    The carry rule for multiplying by 7 is:
full 142857... into 1,
full 285714... into 2,
full 428571... into 3,
full 571428... into 4,
full 714285... into 5,
full 857142 ... into 6

    Please analyze the program flow and fill in the missing codes in the underlined part.


//Calculate the ones digit 
int ge_wei(int a)
{ if(a% 2 == 0) return (a * 2)% 10; else return (a * 2 + 5)% 10; }




//计算进位 
int jin_wei(char* p)
{
char* level[] = {
"142857",
"285714",
"428571",
"571428",
"714285",
"857142"
};

char buf[7];
buf[6] = '\0';
strncpy(buf,p,6);

int i;
for(i=5; i>=0; i--){
int r = strcmp(level[i], buf);
if(r<0) return i+1;
while(r==0){
p += 6;
strncpy(buf,p,6);
r = strcmp(level[i], buf);
if(r<0) return i+1;
______________________________;  //填空
}
}

return 0;
}

//Multiply multiple digits by 7
void f(char* s) 
{ int head = jin_wei(s); if(head> 0) printf("%d", head);

char* p = s;
while(*p){
int a = (*p-'0');
int x = (ge_wei(a) + jin_wei(p+1)) % 10;
printf("%d",x);
p++;
}

printf("\n");
}

int main()
{
f("428571428571");
f("34553834937543");
return 0;
}

 

Problem analysis

Ideas:

For high-order operations, the idea is like this. Each time the first 6-bit character is stored in buf, and compared with the largest level. If it is greater than the largest level, it means the carry is 6, and the rest are also compared in sequence.

Compare buf with level [i], if buf is greater than level [i], it means that the current buf is larger than level [i], so carry is required, and the carry digit is i+1, (the logic here can be obtained from the code in the carry function) . If buf = level[i], it means that the current string of buf is equal to the string of level, then it needs to be compared later, that is, take the last six digits of the original string and store it in buf, and compare with level Carry, just keep comparing like this, the problem is, before it is always buf is greater than level[i], return i+1 (given by the meaning code of the question), then if buf is smaller than level[i], right? Do you want to return a constant value? This is the part to be filled in. You can think about it, buf is larger than the current level [i], and the previous level is returned, so i+1 is returned. Then buf is smaller than the current level, and the return is the i of the current level (by analogy). Try this conjecture, and consider the continuity of the code in the blank fill-in and the previous code. If r <0 in the front, we must consider the situation of r> 0 in the back. Finally, try your guess and verify it with a calculator.

The specific code analysis is as follows:

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

//计算个位?
int ge_wei(int a)
{
	if(a % 2 == 0)
		return (a * 2) % 10;
	else
		return (a * 2 + 5) % 10;
}	

//计算进位?
int jin_wei(char* p)
{
	char* level[] = {
		"142857",
		"285714",
		"428571",
		"571428",
		"714285",
		"857142"
	};
	
	char buf[7];
	buf[6] = '\0';
	strncpy(buf, p, 6);
	
	int i;
	for(i=5; i>=0; i--){
		int r = strcmp(level[i], buf);
		if(r < 0) return i+1;	//level[i] < buf,得出进位数i+1 
		while(r==0){	//level[i] = buf
			p += 6;		//往后偏移6位,看看剩下的6位再比较,就是前面的一样,那么往后比较 
			strncpy(buf,p,6);
			r = strcmp(level[i], buf);
			if(r < 0) //buf 更大 ,进位为前一个i,即i+1 
				return i+1;
//			______________________________; ?//填空
			if(r > 0)	//buf 更小 ,进位为当前为i 
				return i;
		}	
	}
	
	return 0;
}

//多位数乘以7
void f(char* s)
{
	int head = jin_wei(s);	//head是s的进位 
	if(head > 0) printf("%d", head);	//输出进位 
	
	char* p = s;	
	while(*p){
		int a = (*p - '0');	//字符转数字 
		int x = (ge_wei(a) + jin_wei(p+1)) % 10;	//个位+后者字符串的进位取个位 
		printf("%d",x);
		p++;
	}
	
	printf("\n");
}

int main()
{
	f("428571428571");
	f("34553834937543");
	return 0;
}

 

Guess you like

Origin blog.csdn.net/weixin_44566432/article/details/115193755