-
Notifications
You must be signed in to change notification settings - Fork 8
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #244 from pdp-archive/36-luckyagain
36 luckyagain
- Loading branch information
Showing
7 changed files
with
309 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
TASK( | ||
name = "luckyagain", | ||
test_count = 18, | ||
files_dir = "testdata/36-PDP/luckyagain/", | ||
input_file = "luckyagain.in", | ||
output_file = "luckyagain.out", | ||
time_limit = 2, | ||
mem_limit = 128, | ||
solutions = [ | ||
SOLUTION( | ||
name = "luckyagain_efficient", | ||
source = "luckyagain_efficient.cc", | ||
passes_all, | ||
lang = "c++", | ||
), | ||
SOLUTION( | ||
name = "luckyagain_brute_force", | ||
source = "luckyagain_brute_force.cc", | ||
passes_up_to = 11, | ||
lang = "c++", | ||
), | ||
] | ||
) |
62 changes: 62 additions & 0 deletions
62
_includes/source_code/code/36-PDP/luckyagain/luckyagain_brute_force.cc
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,62 @@ | ||
#include <algorithm> | ||
#include <cstdio> | ||
#include <vector> | ||
|
||
typedef long long ll; | ||
|
||
bool is_lucky(const std::vector<int>& digitsA, const std::vector<int>& digitsB) { | ||
int total_length = (digitsA.size() + digitsB.size()); | ||
if (total_length % 2 == 1) return false; // Αν έχει μονό πλήθος ψηφίων, τότε δεν είναι τυχερός. | ||
|
||
int cur_sum[2]; | ||
cur_sum[1] = 0; // Το άθροισμα των ψηφίων του πρώτου μισού. | ||
cur_sum[0] = 0; // Το άθροισμα των ψηφίων του δεύτερου μισού. | ||
|
||
int midpoint = total_length / 2; | ||
for (int i = 0; i < digitsA.size(); ++i) { | ||
cur_sum[i < midpoint] += digitsA[i]; | ||
} | ||
for (int i = 0; i < digitsB.size(); ++i) { | ||
cur_sum[i + digitsA.size() < midpoint] += digitsB[i]; | ||
} | ||
|
||
return cur_sum[0] == cur_sum[1]; | ||
} | ||
|
||
int main() { | ||
FILE *fi = fopen("luckyagain.in", "r"); | ||
long N; | ||
fscanf(fi, "%ld", &N); | ||
|
||
std::vector<std::vector<int>> digits(N); | ||
|
||
for (int i = 0; i < N; ++i) { | ||
long temp; | ||
fscanf(fi, "%ld", &temp); | ||
|
||
// Βρίσκουμε τα ψηφία ενός αριθμού. | ||
while (temp > 0) { | ||
digits[i].push_back(temp % 10); | ||
temp /= 10; | ||
} | ||
// Δεδομένου του υπόλοιπου κώδικα η ακόλουθη αντιστροφή δεν είναι | ||
// αναγκαία (γιατί;) | ||
// std::reverse(digits[i].begin(), digits[i].end()); | ||
} | ||
fclose(fi); | ||
|
||
// Μετράμε πόσα από τα δυνατά ζευγάρια φτιάχνουν έναν τυχερό αριθμό. | ||
ll total_count = 0; | ||
for (long i = 0; i < N; ++i) { | ||
for (long j = 0; j < N; ++j) { | ||
if (i == j) continue; | ||
total_count += is_lucky(digits[i], digits[j]); | ||
} | ||
} | ||
|
||
FILE *fo = fopen("luckyagain.out", "w"); | ||
fprintf(fo, "%lld\n", total_count); | ||
fclose(fo); | ||
|
||
return 0; | ||
} |
75 changes: 75 additions & 0 deletions
75
_includes/source_code/code/36-PDP/luckyagain/luckyagain_efficient.cc
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,75 @@ | ||
#include <cstdio> | ||
#include <vector> | ||
|
||
typedef long long ll; | ||
|
||
ll counts[10 /* πλήθος ψηφίων */][82 /* άθροισμα ψηφίων */]; // Πλήθος αριθμών | ||
|
||
int main() { | ||
FILE *fi = fopen("luckyagain.in", "r"); | ||
long N; | ||
fscanf(fi, "%ld", &N); | ||
|
||
std::vector<std::vector<int>> digits(N); | ||
std::vector<int> digit_sum(N, 0); | ||
|
||
for (int i = 0; i < N; ++i) { | ||
long temp; | ||
fscanf(fi, "%ld", &temp); | ||
|
||
// Βρίσκουμε τα ψηφία ενός αριθμού και το άθροισμά τους. | ||
while (temp > 0) { | ||
int cur_digit = temp % 10; | ||
digit_sum[i] += cur_digit; | ||
digits[i].push_back(cur_digit); | ||
temp /= 10; | ||
} | ||
|
||
// (Προ)-ϋπολογισμός του πίνακα counts. | ||
++counts[digits[i].size()][digit_sum[i]]; | ||
} | ||
fclose(fi); | ||
|
||
ll total_count = 0; | ||
// Οι αριθμοί με το ίδιο πλήθος ψηφίων θα μετρηθούν δύο φορές. Επομένως κρατάμε | ||
// το πλήθος αυτών ώστε να το αφαιρέσουμε το μισό από το σύνολο. | ||
ll same_digit_count = 0; | ||
for (int j = 0; j < N; ++j) { | ||
const int sum_of_digits = digit_sum[j]; | ||
const int len = digits[j].size(); | ||
|
||
// Βρίσκουμε το πλήθος των ζευγαριών που έχουν τον j-οστό αριθμό | ||
// σαν πρώτο μέρος και μέσο η θέση (len - i). | ||
int suffix_sum = 0; | ||
for (int i = 0; 2 * i < len; ++i) { | ||
ll cur_count = counts[len - 2 * i][sum_of_digits - 2 * suffix_sum]; | ||
total_count += cur_count; | ||
if (i == 0) { // Το μέσο είναι στο τέλος του αριθμού. | ||
same_digit_count += cur_count - 1; // -1, για να μην μετρήσουμε τον εαυτό του. | ||
} | ||
suffix_sum += digits[j][i]; | ||
} | ||
|
||
// Βρίσκουμε το πλήθος των ζευγαριών που έχουν τον j-οστό αριθμό | ||
// σαν δεύτερο μέρος και μέσο η θέση i. | ||
int prefix_sum = 0; | ||
for (int i = 0; 2 * i < len; ++i) { | ||
ll cur_count = counts[len - 2 * i][sum_of_digits - 2 * prefix_sum]; | ||
total_count += cur_count; | ||
if (i == 0) { // Το μέσο είναι στην αρχή του αριθμού. | ||
same_digit_count += cur_count - 1; | ||
} | ||
prefix_sum += digits[j][len - i - 1]; | ||
} | ||
|
||
// Αφαιρούμε τον εαυτό του απο την μέτρηση. | ||
total_count -= 2; | ||
} | ||
total_count -= same_digit_count / 2; | ||
|
||
FILE *fo = fopen("luckyagain.out", "w"); | ||
fprintf(fo, "%lld\n", total_count); | ||
fclose(fo); | ||
|
||
return 0; | ||
} |
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Oops, something went wrong.