北郵OJ-94. 最小距離查詢-13計院上機D

算法分析:
算法一:每次查詢直接調用query,並且左右都分別遍歷到盡頭。超時
算法二:優化了“左右分別遍歷到盡頭”的算法,採取了從index開始向兩側同時遍歷,第一次找到相同值就返回。依然超時
算法三:在各種優化了輸入輸出依然超時後,終於意識到問題的本質——m具有可怕的最大值,也就是說將要面對的是海量的查詢次數。
每次查詢都要重新調用query的話會造成時間的嚴重浪費。於是想到使用空間換時間,設置一個dist[],在查詢之前先做一次預處理初始化dist。
然後在以後每次INSERT之後都再從尾至前遍歷一遍,更新一下dist[],在面對海量的查詢時可以節省下大量的時間。

Debug記錄:
1.依然是沒有做好scanf中 %s與%c的過渡
2.scanf時忘寫&了

題目描述
給定一個由小寫字母a到z組成的字符串S,其中第i個字符爲S[i](下標從0開始)。你需要完成下面兩個操作:
INSERT c
其中c是一個待輸入的字符。你需要在字符串的末尾添加這個字符。保證輸入的字符同樣是a到z之間的一個小寫字母。
QUERY x
其中x是一個輸入的整數下標。對於這個詢問,你需要回答在S當中和S[x]相等且與x最近的距離。輸入保證x在當前字符串中合法。
例如S = “abcaba”,如果我們操作:
INSERT a
則在S的末端加一個字符a,S變成”abcabaa”。
接下來操作
QUERY 0
由於S[0] = a,在S中出現的離他最近的a在下標爲3的位置上,距離爲3 - 0 = 3。因此應當輸出3。
接下來,如果
QUERY 4
S[4] = b,S中離它最近的b出現在下標爲1處,距離爲4 - 1 = 3。同樣應當輸出3。
給定初始字符串S和若干操作,對於每個QUERY,你需要求出相應的距離。

HINT 由於輸入數據較大,C/C++中推薦使用scanf進行讀入以獲得更快的讀入速度。同時請注意算法複雜度。

輸入格式
輸入的第一行是一個正整數T(T≤20),表示測試數據的組數。
每組輸入數據的第一行是一個初始串S。第二行是一個正整數m(1≤m≤100000),表示總共操作的數量。接下來m行,每行表示一個操作。操作的格式如上所述。
數據保證在任何情況下,S的長度不會超過100000。

輸出格式
對於每個QUERY,輸出所求的最小距離。如果S中其它位置都不存在和它相同的字符,輸出-1。

輸入樣例
2
axb
3
INSERT a
QUERY 0
QUERY 1
explore
3
INSERT r
QUERY 7
QUERY 1
輸出樣例
3
-1
2
-1


#include <cstdio>
#include <iostream>
#include <cstring>
#define MAXSIZE 100010
using namespace std;
char str[MAXSIZE];
int dist[MAXSIZE];//0±íʾδ²éѯ£¬-1±íʾ²»´æÔÚ 
int len;
void insert(char c){
    int newDist;
    str[len]=c;
    str[len+1]='\0';
    len++;
    int i;
    bool haveFind=false; //±ê¼ÇÊÇ·ñÕÒµ½ÐÂÔªËصÄ×î¶Ì¾àÀë 
    for (i=len-2;i>=0;i--){//´ÓºóÍùÇ°±éÀú¸üÐÂdistµÄÖµ 
        if (str[i]==str[len-1]){
            newDist=len-1-i;
            if(haveFind==false){
                dist[len-1]=newDist;
                haveFind=true;
            }
            if (newDist<dist[i]||dist[i]==-1){
                dist[i]=newDist;
            }
        }
    }
    if (haveFind==false)
        dist[len-1]=-1;
}
int query(int index){
    int lIndex=index-1,rIndex=index+1;
    while (lIndex>=0||rIndex<len){
        if (lIndex>=0&&str[lIndex]==str[index])
            return dist[index]=index-lIndex;
        if (rIndex<len&&str[rIndex]==str[index])
            return dist[index]=rIndex-index;
        lIndex--;rIndex++;
    }
    return dist[index]=-1;
//  while (lIndex>=0&&str[lIndex]!=str[index])
//      lIndex--;
//  while (str[rIndex]!='\0'&&str[rIndex]!=str[index])
//      rIndex++;

//  int lDis=abs(index-lIndex);
//  int rDis=abs(rIndex-index);
//  int minDis;
//  
//  if (lIndex==-1){
//      if (str[rIndex]=='\0')
//          minDis=-1;
//      else
//          minDis=rDis;
//  }
//  else if (str[rIndex]=='\0'){
//      minDis=lDis;
//  }
//  else{
//      minDis=lDis<rDis?lDis:rDis;
//  }
//  return minDis;
}
int main(){
    int t,m;
    char c;
    int index;
    char operation[20];
    scanf("%d",&t);
    //preprocess
    while (t--){
        //initiate
        scanf("%s",str);
        len=strlen(str);
        for (int i=0;i<len;i++){
            dist[len]=0;
        }
        scanf("%d",&m);
        //preprocess
        for (int i=0;i<len;i++){
            query(i);
        }
        //operate
        for (int i=0;i<m;i++){
            scanf("%s",operation);
            if (operation[0]=='I'){
                getchar();
                scanf("%c",&c);/*bug*/
                insert(c);
                //**debug**
//              cout<<str<<endl;
//              return true;
                //********
            }
            else if (operation[0]=='Q'){
                scanf("%d",&index);/*bug*/
                if (dist[index]==0)
                    query(index);
                printf("%d\n",dist[index]);
            }
        }

    }

    return true;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章