This article first http://svtter.cn the nearest number topic
Number N of a K-bit
(k≤2000,n≤1020) (k\leq2000,n\leq10^{20})
Find a number that is larger and closer than N, and the sum of each of the numbers is the same as N and is implemented in code.
For example: 0050 The book number is 0104; 112 is 121; algorithm analysis algorithm thought
Direct violence to ask for this number is not possible, the magnitude of the number is too large, there are k digits of the number, it is not possible to directly use int, or float to represent, using an array to store. This number should be analyzed, STEP1, starting with the minimum number of digits on the right, decomposing the last digit, and breaking it down to the previous one. 9 and 0 are more special, so from the left to the right to scan the beginning, encountered 0 skipped, encountered the first non-0 number, the number 1, and then moved to the last face, and then, Step2, began to find the first non-9 number, if encountered 9, put 9 to the last surface, encountered non 9, 1, end operation.
A like example:
1999000-1990008-> 2000899
One thing to note is that if this is 999000, the first 1 in the number is 1000899.
Several unruly data: 29399-29489 pseudo-code
Array = Get_array () # number to char array
array.reverse ()
Step1 = True
Step2 = false
zero = 0, cnt = 0;
for i:1-Lengthof (array)
if Step1:
if Array[i] is 0:
Zero + +
else:
array[i] = array[i]-1
If zero > 0:
array[0] = Array[i]
array[i] = 0
Step1 = False
Step2 = True
else if Step2:
i F Array[i] is 9:
if zero = = 0:
array[cnt+1] = array[cnt]
array[cnt] = 9
cnt++
if (i! = CNT):
array[i] = Array[i-1]
else:
array[cnt + 1] = array[cnt]
array[cnt] = 9
cnt++
Array[i] = 0
else:
i = i+1
Step2 = False
if not step2:
Array[lengthof (array)] = 1
Array.reverse ()
disp (array)
Analysis of time complexity o
Because the reverse operation, 2K, plus the final finishing minimum number to the front, the worst case approach to k,3k, the operation in the loop to see luck, but the worst case is only 5 K, so the time complexity is
O (3K) ≈o (k) O (3K) \approx O (k)
Source Code
#include <stdio.h> #include <string.h> const int MAXN = 3000;
Char ARRAY[MAXN];
int length_of_number;
void Get_array () {int i;
char null;
scanf ("%d", &length_of_number);
scanf ("%c", &null);
for (i = 0; i < Length_of_number; i++) {scanf ("%c", &array[i]);
} scanf ("%c", &null);
} void reverse () {int i;
char temp;
for (i = 0; i < LENGTH_OF_NUMBER/2; i++) {//_swap temp = array[i];
Array[i] = array[length_of_number-1-i];
Array[length_of_number-1-i] = temp;
}} void Run () {reverse ();
int step1 = 1, Step2 = 0, i = 0, zero = 0, cnt = 0;
for (i = 0; i < Length_of_number; i++) {if (Step1) {if (array[i] = = ' 0 ')
{zero++;
} else {Array[i] = array[i]-1;
if (zero > 0) {array[cnt] = Array[i];
Array[i] = ' 0 ';
} step1 = 0, Step2 = 1; }} else if (STEP2) {if (array[i] = = ' 9 ') {if (zero = = 0
) {array[cnt + 1] = array[cnt];
ARRAY[CNT] = ' 9 ';
cnt++;
if (i! = cnt) {Array[i] = array[i-1];
}} else {array[cnt + 1] = array[cnt];
ARRAY[CNT] = ' 9 ';
cnt++;
Array[i] = ' 0 ';
}} else {Array[i] + +;
Step2 = 0;
Break
}}} if (Step2) {Array[length_of_number] = ' 1 ';
Length_of_number + +; }} void output () {int i;
Reverse ();
for (i = 0; i < Length_of_number; i++) {printf ("%c", Array[i]);
} printf ("\ n");
} int main () {memset (array, 0, sizeof (array));
Freopen ("Input", "R", stdin);
Get_array ();
Run ();
Output ();
return 0; }
Test Results
Use Python to generate test data for testing:
"" "The nearest
number
" ""
import random
import OS
def test ():
"" "" "" "" "num = Random.randint (0, 10000000)
sum_of_num = 0 for
i in STR (num):
sum_of_num + = int (i)
length = Len (str ( num))
temp_num = num + 1 while
(True):
sum_temp = 0 for
i in Str (temp_num):
sum_temp + = int (i)
if Sum_temp = = Sum_of_num: Break
Temp_num + = 1
with open (' Input ', ' W ') as F:
f.write (str (length) + ' \ n ')
f.write (str (num))
res = Os.popen ('./ex2 '). Read ()
if temp_num = = Int (res):
return [True]
Else:
return [False, num, temp_num, int (res)] all
= True for
i in range (+):
res = Test ()
if Res[0] is false: all
= False
print (res)
if all:
print (' Pass testing! ')
Where there is an error:
Pass:
post-improvement optimization of the local reverse is designed for easy processing, but if the number is too large, the speed will certainly be affected, this time do not use reverse. Using a linked list to simplify the code, reduce the analysis, more time to deal with the shift when considering a few questions to find a post water King topic
If the "Water king" is not, but there are three posts a lot of IDs, the number of posts are more than the number of post to do 1/4, and how to quickly find their ID. Algorithm analysis algorithm thought
From the 0-n Scan ID array, record the number of 3 numbers, if there is a fourth number, the number of three numbers is reduced by 1, if the number of a number reduced to 0, then the new number as one of the original three is recorded.
As a result, after the ID array is scanned, the number of the remaining 3 digits that are recorded is the three number required. Pseudo Code
Array = Get_array ()
count = Empty_set () for
i in array:
if count.full:
if I in Count:
count.i.num ++
else: For
J in Count:
count.j.num--
Else
count.add (i)
disp (count)
Analysis of time complexity o
The size of the sequence is n, the array size of the record number is 3, each time you determine whether the record array count is 0, and find the existing number + +, it will take 3 units of time, so its time complexity is
O (3n) ≈o (n) O (3n) \approx O (n)
Source Code
#include <stdio.h> #include <string.h> #define MAXN IDARRAY[MAXN]; int cur[3]; Record current element int pos[3];
Record the current number of elements//check if inside the array, if not inside the array, add into the array void checkin (int no) {int i;
Check if there is an empty location for (i = 0; i < 3; i++) {if (pos[i] = = 0) {Cur[i] = no;
Pos[i] + +;
Return
}//Search for the specified number + + for (i = 0; i < 3; i++) {if (cur[i] = = no) {Pos[i] + +;
Return
}}//No duplicate numbers found, all--for (i = 0; i < 3; i++) pos[i]--;
}//output final result void output () {printf ("%d%d%d\n", cur[0], cur[1], cur[2]);}
Main program int Numberofarray;
void run () {int i;
for (i = 0; i < Numberofarray; i++) {checkin (idarray[i]);
} output ();
} void input () {int i;
scanf ("%d", &numberofarray);
for (i = 0; i < Numberofarray; i++) {scanf ("%d", &idarray[i]);
}} int main () { Freopen ("Input", "R", stdin);
int groupoftest;
scanf ("%d", &groupoftest);
while (groupoftest--) {memset (cur, 0, sizeof (cur));
memset (POS, 0, sizeof (POS));
memset (idarray, 0, sizeof (IDArray));
Input ();
Puts ("Test running ...");
Run ();
} return 0;
}
Test Results
This test data is automatically generated using Python.
"" "
look for the post water King" "
import random
N = 4000
A, B = (int (N/4), int (N/3))
three_id = Random.sample ( Range (1, 3)
three_id_num = {}
sum_rand = 0 for
i in three_id:
temp = Random.randint (A, b)
sum_ Rand + = temp
Three_id_num[i] = three_id_num.get (i, 0) + temp
Id_array = [Random.randint (1) for I in range (N -sum_rand)] for
i in three_id:
id_array = Id_array + [i-J in range (Three_id_num[i])]
random.shuffle (ID _array) print (' Most
three id: ', three_id)
print (' Three ID num: ', three_id_num)
print (' Sum of three_id Num: ', Sum_rand)
print ('---------------')
# Print (Id_array)
with open (' Input ', ' W ') as F:
F.write (' 1\n ')
f.write (str (n) + ' \ n ') for
i in Id_array:
f.write (str (i) + ")
post-improvement optimizations for n smaller cases can be found in memory, but once the larger data is involved, this method may not be as simple as building an array internally, requiring a portion of the read from disk, and if you need to find more IDs, Then the number of temporary saved sequences may be larger; This implementation does not use the map in the STL, if you use a map, it can further make the code easier to understand, map use hash to do internal implementation, can make the face of data volume more data, the speed of finding data. Shanxi Coal boss Topics
You are a coal miner in Shanxi, you have 3000 tons of coal mining in the mining area to be shipped to the market to sell, from your mining area to the market is 1000 kilometers, you have a coal-burning train, the train can only be loaded with 1000 tons of coal, and energy consumption is relatively large-each kilometer needs a ton of coal. Excuse me, as a programmer, how can you transport the coal to the market? Algorithm analysis algorithm thought
The optimal solution is obtained from the angle of dynamic programming:
Suppose that the initial shipment volume is T, the end distance is s, the train capacity is C, the maximum cargo that can reach the end is the function F (t, s).
3 Basic conditions:
(1) T < s: The quantity of goods is not enough to be transported to this distance, so f (t, s) = 0;
(2) s < T < c: The train can load the goods once, so f (t, s) = t-S;
(3) 2s < C so that the train can not be transported once, but may be transported multiple times in a round-trip way, in this case the most way is to reduce the total number of round trip, that is, directly to the end and not unloading in the middle, so
F (t,s) = (t/c−1) ∗ (c−2s) + (c−s)