程序員進(jìn)階之算法練習(xí)(六十四)

題目1

題目鏈接
題目大意:
給出一個(gè)字符串(由26個(gè)大寫字母組成),詢問這個(gè)字符串中,是否相同的字母都連在一起。

輸入:
第一行整數(shù)t,表示有t個(gè)樣例(1≤??≤1000)
每個(gè)樣例兩行,第一行是整數(shù)n,表示字符串長(zhǎng)度 (1≤??≤50)
第二行是字符串
輸出:
如果滿足要求,則輸出YES;
如果不滿足要求,則輸出NO;

Examples
input
5
3
ABA
11
DDBBCCCBBEZ
7
FFGZZZY
1
Z
2
AB

output
NO
NO
YES
YES
YES

題目解析:
用一個(gè)數(shù)組記錄已經(jīng)出現(xiàn)的字符串,從左到右枚舉字符串;
對(duì)于第i個(gè)字符,如果和第i-1個(gè)字符不相同,則判斷是否出現(xiàn)過:
已出現(xiàn)過則不滿足要求;
未出現(xiàn)則標(biāo)識(shí)該字符已出現(xiàn)。

class Solution {
    static const int N = 100010;
public:
    int n, m;
    string str;
public:
    void solve() {
        int t;
        cin >> t;
        while (t--) {
            cin >> n;
            cin >> str;
            int a[256] = {0}, ok = 1;
            a[str[0]] = 1;
            for (int i = 1; i < n; ++i) {
                if (str[i] == str[i-1]) {
                    continue;;
                }
                else {
                    if (a[str[i]]) {
                        ok = 0;
                    }
                    else {
                        a[str[i]] = 1;
                    }
                }
            }
            if (ok) {
                cout << "YES" << endl;
            }
            else {
                cout << "NO" << endl;
            }
        }
    }
}
ac;

題目2

題目鏈接
題目大意:
給出一個(gè)數(shù)字n,求出[1,n]的區(qū)間中,有多少整數(shù)是可以滿足,所有數(shù)字都是相同的。

輸入:
第一行是整數(shù)t,表示有t個(gè)樣例(1≤??≤1e4).
每個(gè)樣例一行,第一行是整數(shù)n(1≤??≤1e9).
輸出:
每個(gè)樣例一行,輸出1到n的整數(shù)中,有多少個(gè)由相同數(shù)字組成的數(shù)。

Examples
input
6
1
2
3
4
5
100

output
1
2
3
4
5
18

題目解析:
如果直接遍歷數(shù)字1到n,可以算出來有多少個(gè)整數(shù)滿足要求。
因?yàn)閚比較比較大,這種做法會(huì)超時(shí)。
注意到滿足要求的數(shù)字應(yīng)該不多,我們可以直接滿足要求的數(shù)字:
先看一位數(shù)的有多少個(gè)數(shù)字;
再看二位數(shù)的有多少個(gè)數(shù)字;
...
直到枚舉出來的數(shù)字,比n還要大。

class Solution {
    static const int N = 100010;
public:
    int n, m;
    string str;
public:
    void solve() {
        int t;
        cin >> t;
        while (t--) {
            cin >> n;
            int ans = 0;
            int current = 1, cnt = 1;
            while (current * cnt <= n) {
                ++ans;
                ++cnt;
                if (cnt > 9) {
                    current = current * 10 + 1;
                    cnt = 1;
                }
            }
            cout << ans << endl;
        }
    }
}
ac;

題目3

題目鏈接
題目大意:
給出一個(gè)數(shù)字n,構(gòu)造n * n的矩陣,要求:
相鄰的數(shù)字,絕對(duì)值之差要大于1;
每個(gè)數(shù)字可以和上下左右,四個(gè)方向的數(shù)字相鄰;
矩陣中的數(shù)字是1~n * n,沒有重復(fù);

輸入:
第一行是整數(shù)t,表示有t個(gè)樣例 (1≤??≤100).
每個(gè)樣例第一行是整數(shù)?? (1≤??≤100).
輸出:
如果有解,則輸出n行,每行n個(gè)整數(shù);
如果無解則輸出-1;

Examples
input
3
1
2
3

output
1
-1
2 9 7
4 6 3
1 8 5

題目解析:
1只有一個(gè)解,2無解;
從3開始,可以采用間隔的方式先填充數(shù)字;
1 0 2
0 3 0
4 0 5
如上,先從上到下,從左到右填充;
最后補(bǔ)齊
1 5 2
6 3 7
4 8 5
因?yàn)槲覀兌际情g隔著填充,相鄰的數(shù)字只差,肯定大于1,滿足要求。

class Solution {
    static const int N = 100010;
public:
    int n, m;
    int a[101][101];
public:
    void solve() {
        int t;
        cin >> t;
        while (t--) {
            cin >> n;
            if (n == 1) {
                cout << 1 << endl;
            }
            else if (n == 2) {
                cout << -1 << endl;
            }
            else {
                int cnt = 1, x = 0, y = 0;
                while (cnt <= n*n) {
                    a[x][y] = cnt;
                    ++cnt;
                    y += 2;
                    if (y >= n) {
                        x += 1;
                        y -= n;
                    }
                    if (x >= n) {
                        x = 0;
                        y = 1;
                    }
                }
                for (int i = 0; i < n; ++i) {
                    for (int j = 0; j < n; ++j) {
                        cout << a[i][j] << " ";
                    }
                    cout << endl;
                }
            }
        }
    }
}
ac;

題目4

題目鏈接
題目大意:
給出n個(gè)數(shù)字的數(shù)組,問數(shù)組中存在多少個(gè)(i, j)的組合,滿足i<j 且 a[j]-a[i]=j-i;

輸入:
第一行是整數(shù)t,表示t個(gè)樣例(1≤??≤1e4).
每個(gè)樣例有2行,第一行是整數(shù)n (1≤??≤2?1e5)
第二行是n個(gè)整數(shù)??1,??2,…,???? (1≤????≤??)

輸出:
輸出滿足要求的組合數(shù)量。

Examples
input
4
6
3 5 1 4 6 6
3
1 2 3
4
1 3 3 4
6
1 6 3 4 5 6

output
1
3
3
10

題目解析:
將題目要求的 a[j]-a[i]=j-i 換一下位置,得到 (a[j] - j)= (a[i] - i);
那么將所有的數(shù)字,減去當(dāng)前的位置,然后排序,即可知道每一組數(shù)字的數(shù)量;
每一組數(shù)字假設(shè)有k個(gè),那么就有k*(k-1)/2的可能。

class Solution {
    static const int N = 200010;
public:
    int n, m;
    int a[N];
public:
    void solve() {
        int t;
        cin >> t;
        while (t--) {
            cin >> n;
            for (int i = 0; i < n; ++i) {
                cin >> a[i];
                a[i] -= i;
            }
            a[n] = 0;
            sort(a, a + n);
            lld ans = 0, cnt = 1;
            for (int i = 1; i<= n; ++i) {
                if (a[i] != a[i - 1]) {
                    ans += cnt * (cnt - 1) / 2;
                    cnt = 1;
                }
                else {
                    ++cnt;
                }
            }
            cout << ans << endl;
        }
    }
}
ac;

題目5

題目鏈接
題目大意:
給出長(zhǎng)度為n的字符串,'*'表示綿羊, '.'表示空地;
每次可以把綿羊移動(dòng)到相鄰的空地,問需要移動(dòng)多少次,才能將所有的綿羊趕在一起。

輸入:
第一行是整數(shù)t,表示t個(gè)樣例(1≤??≤1e4).
每個(gè)樣例有2行,第一行是整數(shù)n (1≤??≤2?1e5)
第二行是字符串

輸出:
最小的移動(dòng)次數(shù)。

Examples
input

 5
 6
 **.*..
 5
 *****
 3
 .*.
 3
 ...
 10
 *.*...*.**

output
1
0
0
0
9

題目解析:
方法1:
暴力,假設(shè)羊最終集中在區(qū)間[left, right]上面,枚舉left的位置,再用貪心從左到右匹配羊的位置。

方法2:
動(dòng)態(tài)規(guī)劃
dpLeft[i]表示,前i個(gè)位置中的所有羊,都集中在位置i左邊;
dpRight[i]表示,[i, n]的位置中所有羊,都集中在位置i的右邊;
這樣只要得到結(jié)果之后,只要枚舉每一個(gè)位置即可。

數(shù)據(jù)范圍較大,沒用long long 錯(cuò)了2次。

class Solution {
    static const int N = 1000010;
public:
    int n, m;
    string str;
    pair<lld, lld> dpLeft[N], dpRight[N]; // first 是最小代價(jià),second的當(dāng)前綿羊數(shù)量
public:
    void solve() {
        int t;
        cin >> t;
        while (t--) {
            cin >> n;
            cin >> str;
            dpLeft[0] = make_pair(0, 0);
            for (int i = 1; i <= n; ++i) {
                char c = str[i - 1];
                if (c == '*') {
                    dpLeft[i].first = dpLeft[i-1].first;
                    dpLeft[i].second = dpLeft[i-1].second + 1;
                }
                else {
                    dpLeft[i].first = dpLeft[i-1].first + dpLeft[i-1].second;
                    dpLeft[i].second = dpLeft[i-1].second;
                }
            }
            dpRight[n+1] = make_pair(0, 0);
            for (int i = n; i > 0; --i) {
                char c = str[i - 1];
                if (c == '*') {
                    dpRight[i].first = dpRight[i+1].first;
                    dpRight[i].second = dpRight[i+1].second + 1;
                }
                else {
                    dpRight[i].first = dpRight[i+1].first+dpRight[i+1].second;
                    dpRight[i].second = dpRight[i+1].second;
                }
            }
            lld ans = dpRight[1].first;
            for (int i = 0; i <= n; ++i) {
                ans = min(ans, dpLeft[i].first + dpRight[i + 1].first);
            }
            cout << ans << endl;
        }
    }
}
ac;
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 230,791評(píng)論 6 545
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 99,795評(píng)論 3 429
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 178,943評(píng)論 0 384
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)。 經(jīng)常有香客問我,道長(zhǎng),這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 64,057評(píng)論 1 318
  • 正文 為了忘掉前任,我火速辦了婚禮,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 72,773評(píng)論 6 414
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 56,106評(píng)論 1 330
  • 那天,我揣著相機(jī)與錄音,去河邊找鬼。 笑死,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 44,082評(píng)論 3 450
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 43,282評(píng)論 0 291
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 49,793評(píng)論 1 338
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 41,507評(píng)論 3 361
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 43,741評(píng)論 1 375
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 39,220評(píng)論 5 365
  • 正文 年R本政府宣布,位于F島的核電站,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 44,929評(píng)論 3 351
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 35,325評(píng)論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,661評(píng)論 1 296
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 52,482評(píng)論 3 400
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 48,702評(píng)論 2 380

推薦閱讀更多精彩內(nèi)容