[ブルーブリッジカップ]リアル試験トレーニング2014C ++ Aグループ質問4ShiFengshouクイック計算

ShiFengshouクイック計算

    Shi Fengshouスピードアルゴリズムの革新的な貢献は、高い位置から数え、キャリーを予測することです。従来の手計算を完全に覆す9つのテーブルは必要ありません!
    迅速な計算の基本は、1桁を複数桁で乗算することです。
    その中で、7を掛けるのが最も複雑です。例として取り上げてください。
    1/7は循環小数0.142857 ...であるため、桁数が142857 ...を超える場合は、1を入力する必要
    があります。2 / 7、3 / 7、... 6 /についても同様です7.循環小数。桁数がn / 7を超える場合は、nの
    下にプログラムを入力して、ShiFengshou速度アルゴリズムで7を掛ける操作プロセスをシミュレートする必要があります。
    7を掛ける1の法則は、偶数を2で掛け、奇数を2で掛け、5を足すというものです。すべてが1だけになります。
    7を掛けるキャリールールは次のとおりです。
フル142857 ...から1、
フル285714 ...から2、
フル428571 ...から3、
フル571428 ...から4、
フル714285 ...から5、
フル857142 ... 6に

    プログラムフローを分析し、下線部分に不足しているコードを入力してください。


// 1桁を計算します 
intge_wei(int a)
{ if(a%2 == 0)return(a * 2)%10; else return(a * 2 + 5)%10; }




// 
计計算決定intjin_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; ______________________________; //ここ空} }









0を返します。
}

//複数の桁に7を掛けますvoidf
(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"); 0を返します。}



 

問題分析

アイデア:

高次演算の場合、アイデアは次のようになります。最初の6ビット文字がbufに格納され、最大レベルと比較されるたびに、最大レベルよりも大きい場合、キャリーは6であり、残りも順番に比較されます。

bufをレベル[i]と比較します。bufがレベル[i]より大きい場合、現在のbufがレベル[i]より大きいことを意味するため、キャリーが必要であり、キャリー桁はi + 1です(ここでのロジックキャリー関数のコードから取得できます)。buf = level [i]の場合、現在のbuf文字列がlevelの文字列と等しいことを意味します。後で比較する必要があります。つまり、元の文字列の最後の6桁を取得して、bufに格納します。レベルキャリーと比較します。このように比較し続けます。問題は、常にbufがlevel [i]よりも大きい前に、i + 1(質問の意味コードで指定)を返し、bufがレベルよりも小さい場合です。 [i]、そうですか?定数値を返しますか?これは記入する部分です。考えてみれば、bufは現在のレベル[i]より大きく、前のレベルが返されるので、i + 1が返されます。その後、bufは現在のレベルより小さく、戻り値は現在のレベルのiです。 (類推による)この推測を試して、空白の塗りつぶしのコードと前のコードの連続性を考慮してください。前のr <0の場合、後ろのr> 0の状況を考慮する必要があります。最後に、推測を試して、電卓で確認します。

具体的なコード分析は次のとおりです。

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

 

おすすめ

転載: blog.csdn.net/weixin_44566432/article/details/115193755