-
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 #245 from pdp-archive/36-bitsign
36 bitsign
- Loading branch information
Showing
10 changed files
with
436 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,35 @@ | ||
TASK( | ||
name = "bitsign", | ||
test_count = 21, | ||
files_dir = "testdata/36-PDP/bitsign/", | ||
input_file = "bitsign.in", | ||
output_file = "bitsign.out", | ||
time_limit = 1, | ||
mem_limit = 256, | ||
solutions = [ | ||
SOLUTION( | ||
name = "bitsign_dp_n2", | ||
source = "bitsign_dp_n2.cc", | ||
passes_all, | ||
lang = "c++", | ||
), | ||
SOLUTION( | ||
name = "bitsign_dp_n2_mem", | ||
source = "bitsign_dp_n2_mem.cc", | ||
passes_all, | ||
lang = "c++", | ||
), | ||
SOLUTION( | ||
name = "bitsign_dp_n3", | ||
source = "bitsign_dp_n3.cc", | ||
passes_all, | ||
lang = "c++", | ||
), | ||
SOLUTION( | ||
name = "bitsign_brute_force", | ||
source = "bitsign_brute_force.cc", | ||
passes_up_to = 8, | ||
lang = "c++", | ||
), | ||
] | ||
) |
58 changes: 58 additions & 0 deletions
58
_includes/source_code/code/36-PDP/bitsign/bitsign_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,58 @@ | ||
#include <cstdio> | ||
#include <vector> | ||
|
||
const long MOD = 1'000'000'007L; | ||
const int MAXN = 2'000; | ||
|
||
char c[MAXN + 2]; | ||
std::vector<int> s; | ||
|
||
long total; | ||
int N, M; | ||
|
||
/* Δοκιμάζουμε τις δυνατές τιμές για το c[c_idx], δεδομένου ότι έχουμε συμπληρώσει | ||
τις τιμές για τα c[0..c_idx-1], ότι έχουμε φτιάξει τα διαστήματα s[0..s_idx-1] και | ||
ότι το μήκος της τωρινής ακολουθίας από άσους είναι len_of_ones. */ | ||
void solve(int c_idx, int len_of_ones, int s_idx) { | ||
if (c_idx == N + 1) { | ||
// Συμπληρώσαμε όλη την ακολουθία. Ελέγχουμε ότι δεν μας περίσσεψε κάτι. | ||
if (s_idx == s.size() && len_of_ones == 0) total = (total + 1) % MOD; | ||
return; | ||
} | ||
// Δοκιμάζουμε να βάλουμε έναν άσο. Επεκτείνεται η τωρινή ακολουθία κατά ένα. | ||
if (c[c_idx] == '1' || c[c_idx] == '.') solve(c_idx + 1, len_of_ones + 1, s_idx); | ||
// Δοκιμάζουμε να βάλουμε ένα μηδενικό. Αν υπάρχει τωρινή ακολουθία από άσσους | ||
// με μήκος s[s_idx], την ολοκληρώνουμε. | ||
if (c[c_idx] == '0' || c[c_idx] == '.') { | ||
if (s_idx < s.size() && len_of_ones == s[s_idx]) solve(c_idx + 1, 0, s_idx + 1); | ||
else if (len_of_ones == 0) solve(c_idx + 1, 0, s_idx); | ||
} | ||
} | ||
|
||
int main() { | ||
FILE *fi = fopen("bitsign.in", "r"); | ||
FILE *fo = fopen("bitsign.out", "w"); | ||
|
||
int T; | ||
fscanf(fi, "%d\n", &T); | ||
while (T--) { | ||
fscanf(fi, "%d %d\n", &N, &M); | ||
for (int i = 0; i < N; ++i) { | ||
fscanf(fi, "%c", &c[i]); | ||
} | ||
c[N] = '0'; | ||
s.resize(M); | ||
for (int i = 0; i < M; ++i) { | ||
fscanf(fi, "%d", &s[i]); | ||
} | ||
|
||
total = 0; | ||
solve(0, 0, 0); | ||
|
||
fprintf(fo, "%ld\n", total); | ||
} | ||
|
||
fclose(fi); | ||
fclose(fo); | ||
return 0; | ||
} |
57 changes: 57 additions & 0 deletions
57
_includes/source_code/code/36-PDP/bitsign/bitsign_dp_n2.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,57 @@ | ||
#include <cstdio> | ||
#include <vector> | ||
|
||
const long MOD = 1'000'000'007L; | ||
const int MAXN = 2'000; | ||
|
||
char c[MAXN + 2]; | ||
|
||
int main() { | ||
FILE *fi = fopen("bitsign.in", "r"); | ||
FILE *fo = fopen("bitsign.out", "w"); | ||
|
||
int T; | ||
fscanf(fi, "%d\n", &T); | ||
while (T--) { | ||
int N, M; | ||
|
||
fscanf(fi, "%d %d\n", &N, &M); | ||
for (int i = 0; i < N; ++i) { | ||
fscanf(fi, "%c", &c[i+1]); | ||
} | ||
c[0] = c[N+1] = '0'; | ||
std::vector<int> s(M); | ||
for (int i = 0; i < M; ++i) { | ||
fscanf(fi, "%d", &s[i]); | ||
} | ||
|
||
// Προϋπολογίζουμε το πρώτο μηδενικό στα δεξιά του κάθε στοιχείου. | ||
std::vector<int> first_zero_to_left(N + 2); | ||
for (int i = N + 1; i >= 0; --i) { | ||
if (c[i] == '0') { | ||
first_zero_to_left[i] = i; | ||
continue; | ||
} | ||
first_zero_to_left[i] = std::min(first_zero_to_left[i+1], i); | ||
while (c[first_zero_to_left[i]] != '0') --first_zero_to_left[i]; | ||
} | ||
|
||
// Ο υπολογισμός με δυναμικό προγραμματισμό. | ||
std::vector<std::vector<int>> dp(M+1, std::vector<int>(N+2, 0)); | ||
for (int i = 0; i <= N+1 && c[i] != '1'; ++i) dp[0][i] = 1; | ||
|
||
for (int j = 1; j <= M; ++j) { | ||
for (int i = 1; i <= N + 1; ++i) { | ||
if (c[i] == '1') continue; | ||
dp[j][i] = dp[j][i-1]; // Μπορούμε απλά να προσθέσουμε ένα 0. | ||
if (i - first_zero_to_left[i - 1] - 1 >= s[j-1]) // Υπάρχουν αρκετά ‘1' ή ‘.'? | ||
dp[j][i] = (dp[j][i] + dp[j - 1][i - s[j-1] - 1]) % MOD; | ||
} | ||
} | ||
fprintf(fo, "%ld\n", dp[M][N+1]); | ||
} | ||
|
||
fclose(fi); | ||
fclose(fo); | ||
return 0; | ||
} |
65 changes: 65 additions & 0 deletions
65
_includes/source_code/code/36-PDP/bitsign/bitsign_dp_n2_mem.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,65 @@ | ||
#include <cstdio> | ||
#include <vector> | ||
|
||
const long MOD = 1'000'000'007L; | ||
const int MAXN = 2'000; | ||
|
||
char c[MAXN + 2]; | ||
|
||
inline int C(int i) { return i & 1; } | ||
|
||
int main() { | ||
FILE *fi = fopen("bitsign.in", "r"); | ||
FILE *fo = fopen("bitsign.out", "w"); | ||
|
||
int T; | ||
fscanf(fi, "%d\n", &T); | ||
while (T--) { | ||
int N, M; | ||
|
||
fscanf(fi, "%d %d\n", &N, &M); | ||
for (int i = 0; i < N; ++i) { | ||
fscanf(fi, "%c", &c[i+1]); | ||
} | ||
c[0] = c[N+1] = '0'; | ||
std::vector<int> s(M); | ||
for (int i = 0; i < M; ++i) { | ||
fscanf(fi, "%d", &s[i]); | ||
} | ||
|
||
// Προϋπολογίζουμε το πρώτο μηδενικό στα δεξιά του κάθε στοιχείου. | ||
std::vector<int> first_zero_to_left(N + 2); | ||
for (int i = N + 1; i >= 0; --i) { | ||
if (c[i] == '0') { | ||
first_zero_to_left[i] = i; | ||
continue; | ||
} | ||
first_zero_to_left[i] = std::min(first_zero_to_left[i+1], i); | ||
while (c[first_zero_to_left[i]] != '0') --first_zero_to_left[i]; | ||
} | ||
|
||
// Ο υπολογισμός με δυναμικό προγραμματισμό. | ||
std::vector<int> dp[2]; | ||
dp[0].resize(N+2, 0); | ||
dp[1].resize(N+2, 0); | ||
for (int i = 0; i <= N+1 && c[i] != '1'; ++i) dp[0][i] = 1; | ||
|
||
for (int j = 1; j <= M; ++j) { | ||
dp[C(j)][0] = 0; | ||
for (int i = 1; i <= N + 1; ++i) { | ||
if (c[i] == '1') { | ||
dp[C(j)][i] = 0; | ||
} else { | ||
dp[C(j)][i] = dp[C(j)][i-1]; // Μπορούμε απλά να προσθέσουμε ένα 0. | ||
if (i - first_zero_to_left[i - 1] - 1 >= s[j-1]) // Υπάρχουν αρκετά ‘1' ή ‘.'? | ||
dp[C(j)][i] = (dp[C(j)][i] + dp[C(j - 1)][i - s[j-1] - 1]) % MOD; | ||
} | ||
} | ||
} | ||
fprintf(fo, "%ld\n", dp[C(M)][N+1]); | ||
} | ||
|
||
fclose(fi); | ||
fclose(fo); | ||
return 0; | ||
} |
49 changes: 49 additions & 0 deletions
49
_includes/source_code/code/36-PDP/bitsign/bitsign_dp_n3.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,49 @@ | ||
#include <cstdio> | ||
#include <vector> | ||
|
||
const long MOD = 1'000'000'007L; | ||
const int MAXN = 2'000; | ||
|
||
char c[MAXN + 2]; | ||
|
||
int main() { | ||
FILE *fi = fopen("bitsign.in", "r"); | ||
FILE *fo = fopen("bitsign.out", "w"); | ||
|
||
int T; | ||
fscanf(fi, "%d\n", &T); | ||
while (T--) { | ||
int N, M; | ||
|
||
fscanf(fi, "%d %d\n", &N, &M); | ||
for (int i = 0; i < N; ++i) { | ||
fscanf(fi, "%c", &c[i+1]); | ||
} | ||
c[0] = c[N+1] = '0'; | ||
std::vector<int> s(M); | ||
for (int i = 0; i < M; ++i) { | ||
fscanf(fi, "%d", &s[i]); | ||
} | ||
|
||
// Ο υπολογισμός με δυναμικό προγραμματισμό. | ||
std::vector<std::vector<int>> dp(M+1, std::vector<int>(N+2, 0)); | ||
for (int i = 0; i <= N+1 && c[i] != '1'; ++i) dp[0][i] = 1; | ||
|
||
for (int j = 1; j <= M; ++j) { | ||
for (int i = 1; i <= N + 1; ++i) { | ||
if (c[i] == '1') continue; | ||
dp[j][i] = dp[j][i-1]; // Μπορούμε απλά να προσθέσουμε ένα 0. | ||
int first_zero_to_left = i - 1; | ||
while (c[first_zero_to_left] != '0') --first_zero_to_left; | ||
if (i - first_zero_to_left - 1 >= s[j-1]) { // Υπάρχουν αρκετά ‘1' ή ‘.'? | ||
dp[j][i] = (dp[j][i] + dp[j - 1][i - s[j-1] - 1]) % MOD; | ||
} | ||
} | ||
} | ||
fprintf(fo, "%ld\n", dp[M][N+1]); | ||
} | ||
|
||
fclose(fi); | ||
fclose(fo); | ||
return 0; | ||
} |
Oops, something went wrong.