Submission #72431968
Source Code Expand
Copy
#include <stdio.h>#include <stdlib.h>#include <string.h>#include <inttypes.h>char str[22];#ifdef OLD_CODEuint64_t memo[22][1 << 22][2];uint64_t calc(int pos, int used, int sati) {uint64_t ans = 0;int char_used = 0;int i;if (str[pos] == '\0') return 1;if (memo[pos][used][sati]) return ~memo[pos][used][sati];for (i = 0; str[i] != '\0'; i++) {int char_idx = str[i] - 'A';if (!((used >> i) & 1) && !((char_used >> char_idx) & 1) && (!sati || str[i] <= str[pos])) {char_used |= 1 << char_idx;
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <inttypes.h>
char str[22];
#ifdef OLD_CODE
uint64_t memo[22][1 << 22][2];
uint64_t calc(int pos, int used, int sati) {
uint64_t ans = 0;
int char_used = 0;
int i;
if (str[pos] == '\0') return 1;
if (memo[pos][used][sati]) return ~memo[pos][used][sati];
for (i = 0; str[i] != '\0'; i++) {
int char_idx = str[i] - 'A';
if (!((used >> i) & 1) && !((char_used >> char_idx) & 1) && (!sati || str[i] <= str[pos])) {
char_used |= 1 << char_idx;
ans += calc(pos + 1, used | (1 << i), sati && str[i] == str[pos]);
}
}
return ~(memo[pos][used][sati] = ~ans);
}
#else
uint64_t data[2][1 << 22][2];
int pc(int x) {
x = (x & 0x55555555) + ((x & 0xaaaaaaaa) >> 1);
x = (x & 0x33333333) + ((x & 0xcccccccc) >> 2);
x = (x & 0x0f0f0f0f) + ((x & 0xf0f0f0f0) >> 4);
x = (x & 0x00ff00ff) + ((x & 0xff00ff00) >> 8);
x = (x & 0x0000ffff) + ((x & 0xffff0000) >> 16);
return x;
}
int cmp(const void* x, const void* y) {
int a = *(const int*)x, b = *(const int*)y;
int pa = pc(a), pb = pc(b);
if (pa != pb) return (pa < pb) - (pa > pb); /* 立っているビット数の降順 */
return (a > b) - (a < b);
}
int usedlist[1 << 22];
#endif
int main(void) {
#ifndef OLD_CODE
int pos, used, sati;
int len, nused, pused;
#endif
if (scanf("%21s", str) != 1) return 1;
#ifdef OLD_CODE
printf("%" PRIu64 "\n", calc(0, 0, 1));
#else
len = (int)strlen(str);
nused = 1 << len;
for (used = 0; used < nused; used++) {
usedlist[used] = used;
}
qsort(usedlist, nused, sizeof(*usedlist), cmp);
for (used = 0; used < nused; used++) {
for (sati = 0; sati <= 1; sati++) {
data[len % 2][used][sati] = 1;
}
}
pused = 1;
for (pos = len - 1; pos >= 0; pos--) {
for (; pused < nused && pc(usedlist[pused]) == pos; pused++) {
used = usedlist[pused];
for (sati = 0; sati <= 1; sati++) {
uint64_t ans = 0;
int char_used = 0;
int i;
for (i = 0; i < len; i++) {
int char_idx = str[i] - 'A';
if (!((used >> i) & 1) && !((char_used >> char_idx) & 1) && (!sati || str[i] <= str[pos])) {
char_used |= 1 << char_idx;
ans += data[(pos + 1) % 2][used | (1 << i)][sati && str[i] == str[pos]];
}
}
data[pos % 2][used][sati] = ans;
}
}
}
printf("%" PRIu64 "\n", data[0][0][1]);
#endif
return 0;
}
/*
桁DPの要領で、指定の文字列を超えないアナグラムが何個あるかを求める
ZYXWVUTSRQPONMLKJIHG
*/
Submission Info
| Submission Time | |
|---|---|
| Task | anagram - アナグラム (Anagram) |
| User | mikecat |
| Language | C23 (GCC 14.2.0) |
| Score | 100 |
| Code Size | 2559 Byte |
| Status | AC |
| Exec Time | 276 ms |
| Memory | 38780 KiB |
Judge Result
| Set Name | Set01 | Set02 | Set03 | Set04 | Set05 | ||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Score / Max Score | 20 / 20 | 20 / 20 | 20 / 20 | 20 / 20 | 20 / 20 | ||||||||||
| Status |
|
|
|
|
|
| Set Name | Test Cases |
|---|---|
| Set01 | 01 |
| Set02 | 02 |
| Set03 | 03 |
| Set04 | 04 |
| Set05 | 05 |
| Case Name | Status | Exec Time | Memory |
|---|---|---|---|
| 01 | AC | 0 ms | 1688 KiB |
| 02 | AC | 276 ms | 38780 KiB |
| 03 | AC | 275 ms | 38648 KiB |
| 04 | AC | 160 ms | 38660 KiB |
| 05 | AC | 276 ms | 38556 KiB |