「AOJ Problem Set from ALDS1問 0~19」の編集履歴(バックアップ)一覧はこちら
追加された行は緑色になります。
削除された行は赤色になります。
会津大学オンラインジャッジALDS 問0~20まで
*Getting Started - Insertion Sort
挿入ソートのステップを表示していく問題。
解法
挿入ソートが何をしているかイメージできたら何の問題もない問題です。
要は数字列を左から整列していき、右へ進むだけです。
右で新しい数字が来たら左にさかのぼって入れる位置を決め、そこまでにいる数を全て右へ一つずつずらします。
#include<stdio.h>
static const int N = 1000;
void trace(int A[], int n){
int i;
for ( i = 1; i <= n; i++ ){
if ( i > 1 ) printf(" ");
printf("%d", A[i]);
}
printf("\n");
}
int main(){
int n, i, j;
int A[N+1];
scanf("%d", &n);
for ( i = 1; i <= n; i++ ) scanf("%d", &A[i]);
trace(A, n);
for(int j=2;j<=n;j++){
int key=A[j];
i=j-1;
while(i > 0 && A[i]>key){
A[i+1]=A[i];
i--;
}
A[i+1]=key;
trace(A,n);
}
return 0;
}
*Getting Started - Greatest Common Divisor
http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=ALDS1_1_B
gcdを実装する問題。
指定通り実装するだけです。
#include<stdio.h>
int gcd(int a,int b){
int c;
while(a!=0){
c=a;
a=b%a;
b=c;
}
return b;
}
int main(){
int a,b;
scanf("%d %d",&a,&b);
printf("%d\n",gcd(a,b));
}
*Getting Started - Prime Numbers
http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=ALDS1_1_C
与えられた数列の中に素数が何個あるか答える問題。
解法
1億までの数しか数列に現れないので、10000までの素数で試し割すれば素数かどうか判別できます。
10000までの素数の列は篩で求めます。
#include<stdio.h>
#include<vector>
std::vector<int> prime_list;
void calc_prime_list(){
int is_prime[10001]={0};
for(int i=2;i<400;i++){
if(is_prime[i]==1)continue;
for(int j=i*2;j<10001;j+=i){
is_prime[j]=1;
}
}
for(int i=2;i<10001;i++){
if(is_prime[i]==0)prime_list.push_back(i);
}
}
bool prime_check(int n){
for(int i=0;i<prime_list.size();i++){
int p=prime_list[i];
if(p*p>n)break;
if(n%p==0)return false;
}
return true;
}
int main(){
calc_prime_list();
int n,ans=0,num;
scanf("%d",&n);
while(n--){
scanf("%d",&num);
ans+=prime_check(num);
}
printf("%d\n",ans);
}
*Sort I - Bubble Sort
http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=ALDS1_2_A
指定通りソートを記述するだけ。
数列の右端から初めて左端へ進みながら小さい数を選んで左右を入れ替えていく。
すると最初の右から左への一巡で、一番小さい数が左端にくる。
あとはそれから左端一個除いた部分で同じ処理を繰り返しこれを繰り返すと最後は全部ソートされる。
#include<stdio.h>
void print(int A[],int n){
for(int i=1;i<n;i++)printf("%d ",A[i]);
printf("%d\n",A[n]);
}
int main(){
int A[102],n,ans=0;
scanf("%d",&n);
for(int i=1;i<=n;i++)scanf("%d",&A[i]);
for(int i=1;i<=n;i++){
for(int j=n;j>i;j--){
if(A[j]<A[j-1]){
int t=A[j-1];
A[j-1]=A[j];
A[j]=t;
ans++;
}
}
}
print(A,n);
printf("%d\n",ans);
}
*Sort I - Selection Sort
http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=ALDS1_2_B
選択ソートを実装しソートの交換回数をこたえる問題。
選択ソートはまず配列を全部見て、一番小さいものを左端に持ってくる。
すると左端は一個でソートされ一番小さいものが左端に来て、残りは未ソートです。
2個めから全部精査しその中で一番小さいものを左から2番目に持ってくれば。
左は一番小さいものが左端に、その次に小さいのが左から2番目とこれを繰り返せばすべてソートされます。
#include<stdio.h>
void print(int A[],int n){
for(int i=1;i<n;i++)printf("%d ",A[i]);
printf("%d\n",A[n]);
}
int main(){
int A[102],n,ans=0;
scanf("%d",&n);
for(int i=1;i<=n;i++)scanf("%d",&A[i]);
for(int i=1;i<=n;i++){
int mini=i;
for(int j=i;j<=n;j++){
if(A[j]<A[mini]){
mini=j;
}
}
if(i!=mini){
int t=A[i];
A[i]=A[mini];
A[mini]=t;
ans++;
}
}
print(A,n);
printf("%d\n",ans);
}
*Sort I - Stability
http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=ALDS1_2_C
バブルソートと選択ソートを行いそれがソート結果が安定であったかどうか判定する問題。
解法
バブルソートは無条件で安定なので常にStableです。
選択ソートは左側を決めてそれと入れ替える数を右側で探す際。
最初に入れ替える数と同じ数が出会った場所をPとし。
そのPより右側で最も小さい数が見つかった場合安定でなくなります。
#include<stdio.h>
#include<algorithm>
#include<string.h>
void print(char A[37][3],int n){
for(int i=1;i<n;i++)printf("%s ",A[i]);
printf("%s\n",A[n]);
}
void BubbleSort(char A[37][3],int n){
for(int i=1;i<=n;i++){
for(int j=n;j>i;j--){
if(A[j][1]<A[j-1][1]){
std::swap(A[j-1][0],A[j][0]);
std::swap(A[j-1][1],A[j][1]);
}
}
}
print(A,n);
printf("Stable\n");//バブルソートは常に安定
}
void SelectionSort(char A[37][3],int n){
bool isStable=true;
for(int i=1;i<=n;i++){
int mini=i,p;
p=mini;
for(int j=i;j<=n;j++){
if(A[j][1]<A[mini][1]){
mini=j;
}else if(A[j][1]==A[i][1]&&i==p){
p=j;
}
}
if(i!=mini){
std::swap(A[i][0],A[mini][0]);
std::swap(A[i][1],A[mini][1]);
if(i<p&&p<mini)isStable=false;
}
}
print(A,n);
printf("%s\n",isStable?"Stable":"Not stable");
}
int main(){
int n;
char A[37][3],B[37][3];
scanf("%d",&n);
for(int i=1;i<=n;i++){
scanf("%s",A[i]);
}
memcpy(B,A,sizeof(A));
BubbleSort(A,n);
SelectionSort(B,n);
}
*Elementary data structures - Reverse Polish Notation
http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=ALDS1_3_A
逆ポーランド記法の数式を処理する問題。
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<stack>
int main(){
int x,x1,x2;
std::stack<int> Stack;
char s[100];
while( scanf("%s", s) != EOF ){
if ( s[0] == '+' ){
x1=Stack.top();
Stack.pop();
x2=Stack.top();
Stack.pop();
Stack.push(x1+x2);
} else if ( s[0] == '-' ){
x1=Stack.top();
Stack.pop();
x2=Stack.top();
Stack.pop();
Stack.push(x2-x1);
} else if ( s[0] == '*' ){
x1=Stack.top();
Stack.pop();
x2=Stack.top();
Stack.pop();
Stack.push(x1*x2);
} else {
Stack.push(atoi(s));
}
}
printf("%d\n",Stack.top());
return 0;
}
*Elementary data structures - Round-Robin Scheduling
http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=ALDS1_3_B
コンピュータのタスク処理手順を題材にした問題。
解法
queueで回せば一発です。
#include<iostream>
#include<queue>
#include<string>
struct S{
std::string name;
int time;
};
int main(){
int n,q;
std::queue<S> qu;
std::cin>>n>>q;
S s;
for(int i=0;i<n;i++){
std::cin>>s.name>>s.time;
qu.push(s);
}
int time=0;
while(qu.empty()==false){
s=qu.front();
qu.pop();
if(s.time-q<=0){
time+=s.time;
std::cout<<s.name<<" "<<time<<"\n";
}else{
time+=q;
s.time-=q;
qu.push(s);
}
}
}
*Elementary data structures - Doubly Linked List
http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=ALDS1_3_C
双方向リンクリストをCで実装する問題。
ポインタ苦手。
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
struct node{
unsigned int key;
struct node *next;
struct node *prev;
};
typedef struct node * NodePointer;
NodePointer nil;
NodePointer listSearch(int key){
/* your code */
NodePointer cur=nil->next;
while(1){
if(cur==nil)return cur;
if(cur->key==key)return cur;
cur=cur->next;
}
}
void init(){
nil = malloc(sizeof(struct node));
nil->next = nil;
nil->prev = nil;
}
void printList(){
NodePointer cur = nil->next;
int isf = 1;
while(1){
if ( cur == nil ) break;
if ( isf == 0) printf(" ");
printf("%d", cur->key);
cur = cur->next;
isf = 0;
}
printf("\n");
}
void deleteNode(NodePointer t){
/* your code */
NodePointer cur ,prev;
if(t!=nil){
cur=t->next;
prev=t->prev;
prev->next=cur;
cur->prev=prev;
if(t->next==nil){
nil->prev=prev;
prev->next=nil;
}
free(t);
}
}
void deleteFirst(){
NodePointer t = nil->next;
if ( t == nil ) return;
deleteNode(t);
}
void deleteLast(){
/* your code */
NodePointer cur=nil->prev;
if(cur==nil)return;
deleteNode(cur);
}
void delete(int key){
/* your code */
NodePointer t;
t=listSearch(key);
if(t==nil)return ;
deleteNode(t);
}
void insert(int key){
NodePointer x;
x = malloc(sizeof(struct node));
x->key = key;
/*
your code
*/
if(nil->next==nil){
nil->prev=x;
}
x->next=nil->next;
x->prev=nil;
nil->next->prev=x;
nil->next=x;
}
int main(){
int key, n, i;
int size = 0;
char com[20];
int np = 0, nd = 0;
scanf("%d", &n);
init();
for ( i = 0; i < n; i++ ){
scanf("%s", com);
if ( com[0] == 'i' ) {
scanf("%d",&key);
insert(key); np++; size++;
}
else if ( com[0] == 'd' ) {
if (strlen(com) > 6){
if ( com[6] == 'F' ) deleteFirst();
else if ( com[6] == 'L' ) deleteLast();
} else {
scanf("%d",&key);
delete(key); nd++;
}
size--;
}
}
printList();
return 0;
}
*Search - Search I
http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=ALDS1_4_A
両方の集合に共通する数字の個数を数える問題。
ソートして尺取虫、std::setを使うのも手。
#include<stdio.h>
#include<algorithm>
int main(){
int S[10001],T[501],n,q,ans=0,p1=0,p2=0;
scanf("%d",&n);
for(int i=0;i<n;i++)scanf("%d",&S[i]);
scanf("%d",&q);
for(int i=0;i<q;i++)scanf("%d",&T[i]);
std::sort(S,S+n);
std::sort(T,T+q);
while(p1<n&&p2<q){
if(S[p1]==T[p2]){
ans++;
p1++;
p2++;
}else if(S[p1]<T[p2]){
p1++;
}else{
p2++;
}
}
printf("%d\n",ans);
}
*Search - Search II
http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=ALDS1_4_B
前の問題と同じでデータ量が多いだけ。
#include<stdio.h>
#include<algorithm>
int main(){
int S[100001],T[50001],n,q,ans=0,p1=0,p2=0;
scanf("%d",&n);
for(int i=0;i<n;i++)scanf("%d",&S[i]);
scanf("%d",&q);
for(int i=0;i<q;i++)scanf("%d",&T[i]);
std::sort(T,T+q);
while(p1<n&&p2<q){
if(S[p1]==T[p2]){
ans++;
p1++;
p2++;
}else if(S[p1]<T[p2]){
p1++;
}else{
p2++;
}
}
printf("%d\n",ans);
}
会津大学オンラインジャッジALDS 問0~20まで
*Getting Started - Insertion Sort
挿入ソートのステップを表示していく問題。
解法
挿入ソートが何をしているかイメージできたら何の問題もない問題です。
要は数字列を左から整列していき、右へ進むだけです。
右で新しい数字が来たら左にさかのぼって入れる位置を決め、そこまでにいる数を全て右へ一つずつずらします。
#include<stdio.h>
static const int N = 1000;
void trace(int A[], int n){
int i;
for ( i = 1; i <= n; i++ ){
if ( i > 1 ) printf(" ");
printf("%d", A[i]);
}
printf("\n");
}
int main(){
int n, i, j;
int A[N+1];
scanf("%d", &n);
for ( i = 1; i <= n; i++ ) scanf("%d", &A[i]);
trace(A, n);
for(int j=2;j<=n;j++){
int key=A[j];
i=j-1;
while(i > 0 && A[i]>key){
A[i+1]=A[i];
i--;
}
A[i+1]=key;
trace(A,n);
}
return 0;
}
*Getting Started - Greatest Common Divisor
http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=ALDS1_1_B
gcdを実装する問題。
指定通り実装するだけです。
#include<stdio.h>
int gcd(int a,int b){
int c;
while(a!=0){
c=a;
a=b%a;
b=c;
}
return b;
}
int main(){
int a,b;
scanf("%d %d",&a,&b);
printf("%d\n",gcd(a,b));
}
*Getting Started - Prime Numbers
http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=ALDS1_1_C
与えられた数列の中に素数が何個あるか答える問題。
解法
1億までの数しか数列に現れないので、10000までの素数で試し割すれば素数かどうか判別できます。
10000までの素数の列は篩で求めます。
#include<stdio.h>
#include<vector>
std::vector<int> prime_list;
void calc_prime_list(){
int is_prime[10001]={0};
for(int i=2;i<400;i++){
if(is_prime[i]==1)continue;
for(int j=i*2;j<10001;j+=i){
is_prime[j]=1;
}
}
for(int i=2;i<10001;i++){
if(is_prime[i]==0)prime_list.push_back(i);
}
}
bool prime_check(int n){
for(int i=0;i<prime_list.size();i++){
int p=prime_list[i];
if(p*p>n)break;
if(n%p==0)return false;
}
return true;
}
int main(){
calc_prime_list();
int n,ans=0,num;
scanf("%d",&n);
while(n--){
scanf("%d",&num);
ans+=prime_check(num);
}
printf("%d\n",ans);
}
*Sort I - Bubble Sort
http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=ALDS1_2_A
指定通りソートを記述するだけ。
数列の右端から初めて左端へ進みながら小さい数を選んで左右を入れ替えていく。
すると最初の右から左への一巡で、一番小さい数が左端にくる。
あとはそれから左端一個除いた部分で同じ処理を繰り返しこれを繰り返すと最後は全部ソートされる。
#include<stdio.h>
void print(int A[],int n){
for(int i=1;i<n;i++)printf("%d ",A[i]);
printf("%d\n",A[n]);
}
int main(){
int A[102],n,ans=0;
scanf("%d",&n);
for(int i=1;i<=n;i++)scanf("%d",&A[i]);
for(int i=1;i<=n;i++){
for(int j=n;j>i;j--){
if(A[j]<A[j-1]){
int t=A[j-1];
A[j-1]=A[j];
A[j]=t;
ans++;
}
}
}
print(A,n);
printf("%d\n",ans);
}
*Sort I - Selection Sort
http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=ALDS1_2_B
選択ソートを実装しソートの交換回数をこたえる問題。
選択ソートはまず配列を全部見て、一番小さいものを左端に持ってくる。
すると左端は一個でソートされ一番小さいものが左端に来て、残りは未ソートです。
2個めから全部精査しその中で一番小さいものを左から2番目に持ってくれば。
左は一番小さいものが左端に、その次に小さいのが左から2番目とこれを繰り返せばすべてソートされます。
#include<stdio.h>
void print(int A[],int n){
for(int i=1;i<n;i++)printf("%d ",A[i]);
printf("%d\n",A[n]);
}
int main(){
int A[102],n,ans=0;
scanf("%d",&n);
for(int i=1;i<=n;i++)scanf("%d",&A[i]);
for(int i=1;i<=n;i++){
int mini=i;
for(int j=i;j<=n;j++){
if(A[j]<A[mini]){
mini=j;
}
}
if(i!=mini){
int t=A[i];
A[i]=A[mini];
A[mini]=t;
ans++;
}
}
print(A,n);
printf("%d\n",ans);
}
*Sort I - Stability
http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=ALDS1_2_C
バブルソートと選択ソートを行いそれがソート結果が安定であったかどうか判定する問題。
解法
バブルソートは無条件で安定なので常にStableです。
選択ソートは左側を決めてそれと入れ替える数を右側で探す際。
最初に入れ替える数と同じ数が出会った場所をPとし。
そのPより右側で最も小さい数が見つかった場合安定でなくなります。
#include<stdio.h>
#include<algorithm>
#include<string.h>
void print(char A[37][3],int n){
for(int i=1;i<n;i++)printf("%s ",A[i]);
printf("%s\n",A[n]);
}
void BubbleSort(char A[37][3],int n){
for(int i=1;i<=n;i++){
for(int j=n;j>i;j--){
if(A[j][1]<A[j-1][1]){
std::swap(A[j-1][0],A[j][0]);
std::swap(A[j-1][1],A[j][1]);
}
}
}
print(A,n);
printf("Stable\n");//バブルソートは常に安定
}
void SelectionSort(char A[37][3],int n){
bool isStable=true;
for(int i=1;i<=n;i++){
int mini=i,p;
p=mini;
for(int j=i;j<=n;j++){
if(A[j][1]<A[mini][1]){
mini=j;
}else if(A[j][1]==A[i][1]&&i==p){
p=j;
}
}
if(i!=mini){
std::swap(A[i][0],A[mini][0]);
std::swap(A[i][1],A[mini][1]);
if(i<p&&p<mini)isStable=false;
}
}
print(A,n);
printf("%s\n",isStable?"Stable":"Not stable");
}
int main(){
int n;
char A[37][3],B[37][3];
scanf("%d",&n);
for(int i=1;i<=n;i++){
scanf("%s",A[i]);
}
memcpy(B,A,sizeof(A));
BubbleSort(A,n);
SelectionSort(B,n);
}
*Elementary data structures - Reverse Polish Notation
http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=ALDS1_3_A
逆ポーランド記法の数式を処理する問題。
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<stack>
int main(){
int x,x1,x2;
std::stack<int> Stack;
char s[100];
while( scanf("%s", s) != EOF ){
if ( s[0] == '+' ){
x1=Stack.top();
Stack.pop();
x2=Stack.top();
Stack.pop();
Stack.push(x1+x2);
} else if ( s[0] == '-' ){
x1=Stack.top();
Stack.pop();
x2=Stack.top();
Stack.pop();
Stack.push(x2-x1);
} else if ( s[0] == '*' ){
x1=Stack.top();
Stack.pop();
x2=Stack.top();
Stack.pop();
Stack.push(x1*x2);
} else {
Stack.push(atoi(s));
}
}
printf("%d\n",Stack.top());
return 0;
}
*Elementary data structures - Round-Robin Scheduling
http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=ALDS1_3_B
コンピュータのタスク処理手順を題材にした問題。
解法
queueで回せば一発です。
#include<iostream>
#include<queue>
#include<string>
struct S{
std::string name;
int time;
};
int main(){
int n,q;
std::queue<S> qu;
std::cin>>n>>q;
S s;
for(int i=0;i<n;i++){
std::cin>>s.name>>s.time;
qu.push(s);
}
int time=0;
while(qu.empty()==false){
s=qu.front();
qu.pop();
if(s.time-q<=0){
time+=s.time;
std::cout<<s.name<<" "<<time<<"\n";
}else{
time+=q;
s.time-=q;
qu.push(s);
}
}
}
*Elementary data structures - Doubly Linked List
http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=ALDS1_3_C
双方向リンクリストをCで実装する問題。
ポインタ苦手。
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
struct node{
unsigned int key;
struct node *next;
struct node *prev;
};
typedef struct node * NodePointer;
NodePointer nil;
NodePointer listSearch(int key){
/* your code */
NodePointer cur=nil->next;
while(1){
if(cur==nil)return cur;
if(cur->key==key)return cur;
cur=cur->next;
}
}
void init(){
nil = malloc(sizeof(struct node));
nil->next = nil;
nil->prev = nil;
}
void printList(){
NodePointer cur = nil->next;
int isf = 1;
while(1){
if ( cur == nil ) break;
if ( isf == 0) printf(" ");
printf("%d", cur->key);
cur = cur->next;
isf = 0;
}
printf("\n");
}
void deleteNode(NodePointer t){
/* your code */
NodePointer cur ,prev;
if(t!=nil){
cur=t->next;
prev=t->prev;
prev->next=cur;
cur->prev=prev;
if(t->next==nil){
nil->prev=prev;
prev->next=nil;
}
free(t);
}
}
void deleteFirst(){
NodePointer t = nil->next;
if ( t == nil ) return;
deleteNode(t);
}
void deleteLast(){
/* your code */
NodePointer cur=nil->prev;
if(cur==nil)return;
deleteNode(cur);
}
void delete(int key){
/* your code */
NodePointer t;
t=listSearch(key);
if(t==nil)return ;
deleteNode(t);
}
void insert(int key){
NodePointer x;
x = malloc(sizeof(struct node));
x->key = key;
/*
your code
*/
if(nil->next==nil){
nil->prev=x;
}
x->next=nil->next;
x->prev=nil;
nil->next->prev=x;
nil->next=x;
}
int main(){
int key, n, i;
int size = 0;
char com[20];
int np = 0, nd = 0;
scanf("%d", &n);
init();
for ( i = 0; i < n; i++ ){
scanf("%s", com);
if ( com[0] == 'i' ) {
scanf("%d",&key);
insert(key); np++; size++;
}
else if ( com[0] == 'd' ) {
if (strlen(com) > 6){
if ( com[6] == 'F' ) deleteFirst();
else if ( com[6] == 'L' ) deleteLast();
} else {
scanf("%d",&key);
delete(key); nd++;
}
size--;
}
}
printList();
return 0;
}
*Search - Search I
http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=ALDS1_4_A
両方の集合に共通する数字の個数を数える問題。
ソートして尺取虫、std::setを使うのも手。
#include<stdio.h>
#include<algorithm>
int main(){
int S[10001],T[501],n,q,ans=0,p1=0,p2=0;
scanf("%d",&n);
for(int i=0;i<n;i++)scanf("%d",&S[i]);
scanf("%d",&q);
for(int i=0;i<q;i++)scanf("%d",&T[i]);
std::sort(S,S+n);
std::sort(T,T+q);
while(p1<n&&p2<q){
if(S[p1]==T[p2]){
ans++;
p1++;
p2++;
}else if(S[p1]<T[p2]){
p1++;
}else{
p2++;
}
}
printf("%d\n",ans);
}
*Search - Search II
http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=ALDS1_4_B
前の問題と同じでデータ量が多いだけ。
#include<stdio.h>
#include<algorithm>
int main(){
int S[100001],T[50001],n,q,ans=0,p1=0,p2=0;
scanf("%d",&n);
for(int i=0;i<n;i++)scanf("%d",&S[i]);
scanf("%d",&q);
for(int i=0;i<q;i++)scanf("%d",&T[i]);
std::sort(T,T+q);
while(p1<n&&p2<q){
if(S[p1]==T[p2]){
ans++;
p1++;
p2++;
}else if(S[p1]<T[p2]){
p1++;
}else{
p2++;
}
}
printf("%d\n",ans);
}
*Search - Search III
まあそのstd::setを使えば一発だったんだけど。
一応ハッシュテーブルの学習用問題だと考えて計算。
ハッシュ関数の作りが適当なのはここだけの秘密、ただしい32ビットハッシュ関数の作り方ってどんなんだろう?
AOJやっててよかったことは今のところ何もないので、評価値が下がろうが気にしない。
#include<stdio.h>
#include<string.h>
#include<list>
const int LIMIT =((1<<16)+33);
std::list<int> hashTable[LIMIT];
int h1(char *str){
int p,p1,num,result=0;
char c;
for(p=0;p<strlen(str);p++){
c=str[p];
num=0;
if(c=='A')num=0;
if(c=='C')num=1;
if(c=='G')num=2;
if(c=='T')num=3;
p1=(p%8)*2;
result=((num<<p1)^result);
}
return result%LIMIT;
}
int h2(char *str){
int num,result=0,b=1;
char c;
for(int p=0;p<strlen(str);p++){
c=str[p];
num=1;
if(c=='A')num=1;
if(c=='C')num=2;
if(c=='G')num=3;
if(c=='T')num=4;
result+=num*b;
b*=5;
}
return result;
}
bool find(char *str){
int H1=h1(str);
int H2=h2(str);
for(std::list<int>::iterator it=hashTable[H1].begin();it!=hashTable[H1].end();it++){
if(H2==(*it))return true;
}
return false;
}
void insert(char *str){
if(find(str)==false){
hashTable[h1(str)].push_front(h2(str));
}
}
int main(){
int n;
char str[14],com[10];
scanf("%d",&n);
while(n--){
scanf("%s %s",com,str);
if(com[0]=='i'){
insert(str);
}else{
printf("%s\n",find(str)?"yes":"no");
}
}
}