HDU - 4886 (hash + 폭력 매 거)
3065 단어 사유 가 좋 은 문제우수 알고리즘 총화HDU
사고방식: ans 의 길이 가 가장 긴 것 은 7 로 추정 할 수 있다. 왜냐하면 메 인 문자열 s 에 모든 8 개의 문자 가 존재 하 는 배열 의 길 이 는 8 ^ 7 이 어야 하기 때문에 제목 이 정 한 길 이 를 초과 했다.모든 길이 의 하위 문자열 을 열거 한 다음 문자열 하 쉬 를 진수 로 만 듭 니 다. 8 진법 일 수도 있 고 9 진법 일 수도 있 지만 둘 은 다 를 수 있 습 니 다.
8 진법 은 AABCAD 가 001203 (기수 8) 에 대응 하고 int 범 위 를 폭발 시 키 지 않 는 다 는 것 이 분명 하 다.매 거 진 길이 1 - 7 의 모든 하위 문자열 은 8 진법 으로 해시 표 에 존재 합 니 다. 매 거 진 전에 해시 표를 비 워 야 합 니 다. 그리고 어 릴 때 부터 해시 표를 옮 겨 다 니 며 첫 번 째 사용 하지 않 은 아래 표 시 를 문자열 로 출력 하면 됩 니 다. 0 은 A 를 표시 할 수도 있 고 AAA 를 표시 할 수도 있 기 때문에 자릿수 (하위 문자열 길이) 가 부족 할 때 선도 0 을 통 해 'A' 를 추가 합 니 다.
9 진 AABCAD 는 112314 (기수 9) 에 대응 하고 int 가 터 지지 않 기 때문에 모든 9 진 에 0 이 존재 하 는 수 는 합 법 적 이지 않 으 며 문자열 로 변환 하 는 과정 에서 어느 때 남 은 수가 9 를 제거 할 수 있다 는 것 을 발견 하면 9 진 이 0 으로 바 뀌 는 것 이 비합법적 이다.첫 번 째 합 법 적 인 아래 표 시 를 찾 아 문자열 로 변환 하면 ans 입 니 다.
Code(base 8):
#include
using namespace std;
const int maxn = 1e6+5;
char s[maxn], ans[10];
int hs[maxn*3], wei[10];
int main()
{
int t, len, k, cnt;
wei[0] = 1;
for(int i = 1; i <= 7; ++i) wei[i] = wei[i-1]*8;
scanf("%d", &t);
for(int _ = 1; _ <= t; ++_)
{
scanf("%s", &s);
len = strlen(s);
for(int i = 1; i <= 7; ++i)
{
memset(hs, 0, sizeof hs);
for(int j = 0; j < len; ++j)
{
if(j+i > len) break;
k = 0;
for(int l = 0; l < i; ++l)
{
k = k*8 + (s[j+l]-'A');
}
++hs[k];
}
cnt = 0;
for(int j = 0; j < wei[i]; ++j)
if(!hs[j])
{
for(int l = i-1; l >= 0; --l)
{
printf("%c", j/wei[l] + 'A');
j %= wei[l];
}
puts(""); cnt = -1;
break;
}
if(cnt == -1) break;
}
}
return 0;
}
Code(base 9):
#include
using namespace std;
const int maxn = 1e6+5;
char s[maxn], ans[10];
int vis[maxn*6], wei[10];
int main()
{
wei[0] = 1;
for(int i = 1; i <= 7; ++i) wei[i] = wei[i-1]*9;
int t, len, cnt, tmp;
scanf("%d", &t);
for(int _ = 1; _ <= t; ++_)
{
scanf("%s", &s);
len = strlen(s);
memset(vis, 0, sizeof vis);
for(int i = 1; i <= 7; ++i)
{
if(i > len) break; tmp = 0;
for(int j = 0; j < i; ++j)
tmp = tmp*9 + (s[j]-'A'+1);
vis[tmp] = 1;
for(int j = i; j < len; ++j)
{
tmp = tmp%wei[i-1];
tmp = tmp*9 + (s[j]-'A'+1);
vis[tmp] = 1;
}
}
for(int j = 1, k; j < maxn*6; ++j)
if(!vis[j])
{
tmp = j, cnt = 0;
while(tmp && tmp%9)
{
ans[cnt++] = 'A'+tmp%9-1;
tmp /= 9;
}
if(!tmp)
{
ans[cnt] = '\0';
break;
}
}
reverse(ans, ans+cnt);
printf("%s
", ans);
}
return 0;
}
계속 파 이 팅 ~
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
삼 분 법 구 철 성 함수 극 대 극소 값직접 템 플 릿 을 붙 이 고 이해 하기 쉬 우 니 인터넷 의 문 제 를 풀 어 보면 된다. 에이, 사내 아 이 를 붙 여 라.http://blog.csdn.net/pi9nc/article/details/966662...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.